使用TypeScript,有什么方法可以强制执行非重新分配吗?
说我有这个:
fn.foo = 5;
fn.foo = 6;
有没有办法在第二行得到编译错误?一旦分配了foo属性,我应该是ReadOnly
。
我的情况foo可以坚持使用此界面:
export interface RO {
[readonly key: string]: any
}
但我不确定该语法是否可行。
答案 0 :(得分:2)
如果使用类,则可以将字段本身标记为readonly
,并且只能在构造函数中进行分配:
class Test {
readonly foo : string;
constructor () {
this.foo = "";
}
}
let fn = new Test();
fn.foo = "" // Error
如果使用的是对象文字,则可以使用显式类型来禁止仅对字段进行初始赋值的突变:
let fn : {
readonly foo: string
} = {
foo: "1"
}
您还可以使用具有运行时行为的Object.freeze
:
let fn = Object.freeze({
foo: "1"
})
fn.foo = "" // error
在任何一种情况下,您都可以创建一个readonly
字段,该字段只能在对象创建时分配。像您的示例一样,无法创建只能在初始化后分配一次的字段。
修改
请注意,readonly
不是很强,它不会导致具有相同字段的两种类型之间的类型不兼容:
let fn = Object.freeze({
foo: "1"
}) // foo is readonly
let nonReadonlyFn : { foo: string } =fn; // foo is not readonly but assignment is allowed
nonReadonlyFn.foo = "" // not a compiler error.
更新
如果您不知道密钥,则可以创建一个只读索引签名:
let fn: {
readonly [n: string] : string
} = { foo: "" };
fn["foo"] ="" // error
console.log(fn["foo"])
创建只读对象而无需一次初始化所有对象的一种常见方法是拥有一个可变的版本,对其进行变异,并在完成将其分配给只读版本之后:
let fnNotReadOnly: {
[n: string] : string
} ;
fnNotReadOnly["foo"] = "";
//When done mutating:
let fn : {
readonly [n: string] : string
} = fnNotReadOnly;
fn["foo"] = ""
console.log(fn["foo"])