这种用法很简单:作为契约,函数doSomething
声明它不会改变接收的参数。
interface Counter {
name: string
value: number
}
function doSomething(c: Readonly<Counter>) {
// ...
}
let c = {
name: "abc",
value: 123
}
doSomething(c)
// Here we are sure that 'c.name' is "abc" and 'c.value' is '123'
使用此代码:
interface Counter {
readonly name: string
readonly value: number
inc(): number
}
function counterFactory(name: string): Counter {
let value = 0
return {
get name() {
return name
},
get value() {
return value
},
inc() {
return ++value
}
}
}
我们这里有一个成员readonly value
,无法直接从外部修改。但是成员inc()
可以改变该值。此外,成员value
被声明为readonly
,但其值正在发生变化。
我想知道在成员readonly
上使用value
是否是一种很好的方法。语法没问题。但是这个示例在TypeScript中是否在语义上正确?那是修饰语readonly
的用途吗?
答案 0 :(得分:2)
属性上的readonly
关键字不能确保属性值是常量。没有类似的TypeScript。我们可以确定只读属性的唯一事项是:
counterFactory
返回类型,则推断它与Counter
接口完全相同,请参阅下面的代码中的(A)。 代码示例:
// (A) Usage 2 using type inference
const counter = counterFactory('foo');
type Counter = typeof counter; // Produce the exact same type as the previous `Counter` interface
counter.value = 10; // [Ts Error] Can not assign to 'value' because it is a constant or read-only property
// (B) Readonly property initialization
// (B1) With an object literal + interface
const manualCounter: Counter = { name: 'bar', value: 2, inc: () => 0 };
manualCounter.value = 3; // [Ts Error] Can not assign...
// (B2) With a class
class Foo {
constructor(public name: string, public readonly value: number) { }
inc() {
return ++this.value; // [Ts Error] Can not assign...
}
}
const foo = new Foo('bar', 3);
foo.value = 4; // [Ts Error] Can not assign...
// (C) Circumvent TypeScript
Object.assign(foo, { value: 4 }); // → No error neither in Ts, nor at runtime
它真的令人困惑,因为它几乎就像一个不变的财产!用法2和案例C证明它不是。
答案 1 :(得分:0)
造成混乱的是&#34; double&#34;使用'value&#39;在你的工厂功能。
澄清一下,用这种方式重写(请注意_value
变量前面的_):
interface Counter {
readonly name: string
readonly value: number
inc(): number
}
function counterFactory(name: string): Counter {
let _value = 0
return {
get name() {
return name
},
get value() {
return _value
},
inc() {
return ++_value
}
}
}
_value
只是一个局部var而不是你可以改变get value()
实现了界面定义readonly value: number
:counter.value
readonly