如何修复“属性没有初始值设定项并且未在构造函数中明确分配”错误?

朱利安

我对这些课程有问题。我想使用doSomething()class 独有的方法B而不是每次都对其进行类型转换,但是当我将 property 指定a为 type 时B,它告诉我它没有在构造函数中分配,这有点错误,因为父构造函数进行了分配。

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()
  }
}

我做错了什么?

游乐场

杰卡兹

问题在于,将类字段声明添加到 JavaScript的提议与您可能期望的语义以及 TypeScript 设计人员将它们添加到 TypeScript 时所期望的语义不同。事实证明,在 JavaScript 中,类字段声明将通过Object.defineProperty()而不是通过赋值来初始化,并且所有此类没有初始化器的声明字段都将使用undefined. 因此,最终您可以期望像您这样的代码生成在子类中设置a为 的JavaScript,undefined即使您的目的只是从基类中缩小类型。布莱奇。

因此,在 TypeScript 3.7 中,添加了一个--useDefineForClassFields标志以及declare属性修饰符如果使用--useDefineForClassFields,编译器将输出符合Object.defineProperty()类字段预期语义的代码

如果您使用该标志按原样运行代码,您将在运行时看到问题:

new Two().doStuff()
// [ERR]: "Executed JavaScript Failed:" 
// [ERR]: this.a is undefined 

解决方案是使用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

Playground 链接到代码

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

属性“searchText”没有初始值设定项,并且在构造函数中没有明确分配?

属性“ form”没有初始化程序,并且在构造函数中未明确分配

属性“ ...”没有初始化程序,并且在构造函数中未明确分配

如何在varargs构造函数的初始值设定项列表中初始化向量?

错误:LINQ to Entities 中仅支持无参数构造函数和初始值设定项

如何在带有初始值设定项的构造函数中使用 vprintf/cstdarg 功能?

如何使用Clang-AstMatcher获取所有构造函数的初始值设定项?

IBInspectable属性在initWithCoder中没有其值:初始值设定项

使用@Input装饰器时,如何解析“属性'foo'没有初始化程序,并且在构造函数中未明确分配”?

属性没有初始化器,并且在构造函数中没有明确赋值

我该如何解决打字稿错误“ x”没有初始化程序并且在构造函数中未明确分配?

C ++:构造函数初始值设定项列表的替代形式,无需分配?

Vue Prop没有初始化程序,并且在构造函数中未明确分配

在C#构造函数初始值设定项中使用默认属性值

如何在 C++ 构造函数初始值设定项列表中初始化非内置类型的数组?

子类是否需要构造函数/初始值设定项?

启用默认的初始值设定项列表构造函数

构造函数与数组初始值设定项的歧义

构造函数采用初始值设定项列表

构造函数初始值设定项列表中的非成员初始化

似乎对象初始值设定项与构造函数+属性赋值不同。为何如此?

LINQ中仅支持无参数构造函数和初始值设定项与linq中带有元组的实体

如何修复“无法在属性初始值设定项中使用实例成员‘textField_1’;属性初始值设定项在‘self’可用之前运行”?

ngx-bootstrap modal - 属性 'modalRef' 没有初始化器,并且在构造函数中没有明确分配

无法构造“任务”,因为它没有可访问的初始值设定项

实例初始值设定项和构造函数之间有什么区别?

TypeScript是否支持带有对象初始值设定项的构造函数?

带有成员初始值设定项列表的构造函数定义

构造函数初始值设定项列表中的共享参数