有可能创建一个“只写”对象吗?

前端开发 2026-07-09

我想要一个对象,允许写入属性但不能读取属性,例如:

var foo: WriteOnly = {};
foo.bar = "yes"
foo.bar // type error

在一个项目中,我曾设想有一个全局对象,数据可以写入用于分析。运行时调试的人能够访问它。但我希望人们知道他们不应该在应用内通过该对象传递数据。

解决方案

这在TypeScript中是不可能的。属性可以通过 readonly 修饰符或 the Readonly 实用类型 将其设为只读,但在类型层面无法将其标记为只写属性。

你可以改用一个设置属性但不暴露任何属性的方法。

使用一个包装类:

class WriteOnly<K extends PropertyKey, V> {
  private _myValues: Partial<Record<K, V>> = {};

  public setValue(key: K, value: V) {
    this._myValues[key] = value;
  }
}

const foo = new WriteOnly<string, string>();

foo.setValue("bar", "yes"); // the only thing allowed

Playground链接

或用一个 Map 实现:

class WriteOnly<K extends PropertyKey, V> {
  private _myValues: Map<K, V> = new Map<K, V>();

  public setValue(key: K, value: V) {
    this._myValues.set(key, value);
  }
}

const foo = new WriteOnly();

foo.setValue("bar", "yes"); // the only thing allowed

Playground链接

另外,也可以直接使用Map,并在类型层面去除一切可能改变其中值的内容。这在类型层面很容易实现,但你需要一个返回新Map的函数:

type WriteOnlyMap<K, V> = Pick<Map<K, V>, "set" | "delete" | "clear">;

function createWriteOnlyMap<K, V>(): WriteOnlyMap<K, V> { 
  return new Map<K, V>();
}

Playground链接

这让 set()delete()clear() 可以被调用,但不允许其他任何操作:

foo.set("bar", "yes"); // allowed
foo.delete("bar");     // allowed
foo.clear();           // allowed

foo.forEach();         // not allowed
foo.entries();         // not allowed
foo.get("bar");        // not allowed
foo.has();             // not allowed

for(const entry of foo){} // not allowed
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章