Jul*_*ián 5 typescript typescript-class
我对这些课程有疑问。我想使用doSomething()类独有的方法B,而不是每次都对其a进行类型转换,但是当我将属性指定为 typeB时,它告诉我它没有在构造函数中分配,这有点错误,因为父构造函数执行分配。
class A {
}
class B extends A {
doSomething() { }
}
class One {
constructor(protected a: A){ }
}
class Two extends One {
protected a: B // Property 'a' has no initializer and is not definitely assigned in the constructor.
constructor(){
super(new B());
// If I enter "this.a = new B();" here then the error disappears, but the code is redundant.
}
doStuff() {
this.a.doSomething()
}
}
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
问题在于,向 JavaScript 添加类字段声明的提议与您可能期望的语义以及 TypeScript 设计者将类字段声明添加到 TypeScript 时所期望的语义不同。事实证明,在 JavaScript 中,类字段声明将通过Object.defineProperty()而不是通过赋值来初始化,并且所有此类没有初始化器的声明字段都将使用undefined. 因此,最终您可以期望像您这样的代码生成在子类中设置为 的 JavaScript a,undefined即使您的目的只是缩小基类的类型。布莱奇。
因此,在 TypeScript 3.7 中,添加了一个--useDefineForClassFields标志以及declare属性修饰符。如果您使用--useDefineForClassFields,编译器将输出符合Object.defineProperty()类字段预期语义的代码:
如果您使用该标志按原样运行代码,您将在运行时看到问题:
new Two().doStuff()
// [ERR]: "Executed JavaScript Failed:"
// [ERR]: this.a is undefined
Run Code Online (Sandbox Code Playgroud)
解决方案是使用declare属性修饰符来缩小子类属性的范围,而不发出任何相应的Object.defineProperty()代码:
class Two extends One {
declare protected a: B // okay
constructor() {
super(new B());
}
doStuff() {
this.a.doSomething()
}
}
new Two().doStuff(); // okay now
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5967 次 |
| 最近记录: |