以下是我的代码段:
class Hello {
abc = {
a: 'l',
b: 1,
}
k = (prop: keyof typeof Hello.prototype.abc) => {
console.log(prop)
}
}
并且该代码在TypeScript官方游乐场中可以正常工作。
所以我的问题是:abc
类的实例成员是Hello
,为什么可以从中访问该abc
属性Hello.prototype
?
问题是,对于class X {...}
,类型X.prototype
在TypeScript中表示为X
类实例的类型。从(已过时但仍与此问题相关)TypeScript语言规范:
由类声明引入的构造函数的类型称为构造函数类型。构造函数的类型具有以下成员:
... [片段] ...
- 一个名为“ prototype”的属性,该属性的类型是类类型的实例化,其中为每个type参数提供类型Any。
因此TypeScript认为的类型Hello.prototype
为Hello
。当然,通常这不是正确的。正如您所发现的,方法确实适用,但实例属性并非如此。
我在Github中 搜索了所有问题, 但没有发现任何提及此问题的信息。值得一提一个新问题,建议将类原型的类型扩展为仅包括方法。
编辑:糟糕,我猜想对此存在一些现存的问题,从本质上讲,这些建议都是被拒绝的,因为它所带来的伤害大于所能解决的问题。
我知道这样做会弄乱某些东西(目前,x instanceof Class
检查会将x
类型Class['prototype']
简化为,如果将其扩展为仅包含方法,则会在每个地方破坏每个人的代码),所以我怀疑他们是否会采用这样的方法建议。 但是,在此问题上有一个地方可以作为官方用语是很好的。
无论如何,备份您的问题...运行时代码很好,对吧?而且您希望它能正常工作:
new Hello().k("a");
并希望在编译器警告
new Hello().k("oopsie"); // error
?如果是这样,那么我建议您prototype
完全摆脱等式,并在实例类型上改用查找类型Hello
:
class Hello {
abc = {
a: 'l',
b: 1,
}
k = (prop: keyof Hello['abc']) => {
console.log(prop)
}
}
现在,它的行为符合预期,并且不会暴露TypeScript中实例属性和类原型的怪异之处。
好的,希望能有所帮助。祝好运!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句