在用打字本编写属性设置器时,不需要同时包含一个getter:
set name(name: string)
{
...
}
但是,当通过this.name
访问相应的属性getter (未定义)时,它不是编译时错误,而是返回值undefined
。我不明白为什么,也找不到任何关于它的讨论。
const theName = this.name; // undefined at runtime, but typed as 'string'
我最有可能在这种情况下意外结束,这可能会浪费大量的时间,在罕见的情况下,我没有立即注意到。
定义一个属性的“传统”方式是这样的,所以这也许可以解释为什么做出这个决定。
Object.defineProperty(Dog.prototype, "name", {
set: function (name) {
},
enumerable: false,
configurable: true
});
当然,这是一厢情愿的想法,但我会很多,更确切地说,我的行为是返回传入的原始“原始”值--这将是令人惊奇的。避免这种可怕的混乱:-/
set name(name: string)
{
this._name = name;
doNameStuff(name);
}
get name()
{
return this._name;
}
private _name!: string;
发布于 2021-10-25 23:40:56
是的,这是TypeScript的一个安全漏洞。编译器很乐意让您编写一个没有对应的set
访问器的get
属性访问器,但是它不能很好地建模该属性的结果行为。从概念上讲,带有setter但没有getter的属性应该是"writeonly
“,就像带有getter但没有setter的属性是readonly
一样。实际上,如果您编写了一个getter但没有setter,编译器就会推断该属性是readonly
。
const foo = {
get bar() { return 1 }
}
/* const foo: {
readonly bar: number;
} */
但是,在writeonly
中,目前还没有TypeScript这样的东西,编译器反而将这样的属性建模为普通的读-写属性:
const baz = {
set qux(x: number) { }
}
/* const baz: {
qux: number;
} */
有一个长期悬而未决的问题要求在writeonly
上使用微软/打字稿#21759属性,但还不清楚它是否或何时会被解决。
TypeScript 4.3引入了对变体存取器的一些支持,它允许类型系统对不同的getter和setter类型进行建模。但目前有一项要求,即getter类型需要分配给setter类型。您不能表示设置者接受(比方说) number
,但是getter总是生成undefined
。因此,微软/打字稿#43662还有另一个悬而未决的问题,要求在setter和getter中提供不相关的类型。如果实现了,这将是另一种建模无getterless设置器的方法;读取该属性将始终生成undefined
。不过,现在还不清楚这是否会被实现。
还有一些建议认为,仅仅让没有getterless的setter成为编译器错误,例如微软/打字稿#30852,但这看起来会被拒绝,因为这将是对现有TypeScript代码的重大更改……虽然在我看来,它只会破坏已经做了奇怪事情的代码。但我不负责。
无论如何,正如我评论中提到的所指出的,我现在唯一能想到的建议就是有人使用ESLint访问器对 linter规则。如果您忘记了getter,这个规则会抱怨,所以至少您会被迫编写更安全的代码。
https://stackoverflow.com/questions/69715657
复制相似问题