【问题标题】:TypeScript complain "has no initializer and is not definitely assigned in the constructor" about constructors by returning constructed objectTypeScript 通过返回构造对象抱怨构造函数“没有初始化程序,并且没有在构造函数中明确分配”
【发布时间】:2019-06-03 21:02:42
【问题描述】:

TypeScript 对此代码示例显示以下错误消息:

class MyClass {
  someField: boolean;
  constructor() {
    return { someField: true };
  }
}

属性 'someField' 没有初始化器,也没有在构造函数中明确分配。


(属性)MyClass.someField:布尔值

TypeScript Playground(您需要启用strictNullChecksstrictPropertyInitialization 才能看到此错误消息。)

给定的代码 sn-p 是从我的原始脚本简化而来的。我想返回构造的值,而不是在构造函数中为 this 赋值。我应该怎么做才能使 TypeScript 正常工作而没有提到的错误?

【问题讨论】:

  • 你的代码没有意义。为什么要尝试从构造函数返回值?为什么要尝试返回一个不是类实例的值?
  • @IanKemp return 在构造函数中是完全有效的(至少在 JavaScript 中)。我会认为 TypeScript 是 JavaScript 的超集。那么为什么它没有意义。您可能会获得有关如何编写 JavaScript 构造函数的更多信息from MDN
  • 但这不是普通的 JavaScript,它是 Typescript,TS 存在的原因之一是防止你做一些 JavaScript 允许的奇怪和荒谬的事情,并返回非@987654327 @ 来自构造函数的值肯定属于“奇怪和荒谬的”。如果你要在TS中写JS,就写JS吧!

标签: typescript constructor


【解决方案1】:

它认为 {someField: true} 是一个新对象,并且 someField 的属性还没有被初始化。在构造函数中返回的目的是什么?您可以将其替换为this.someField = true

编辑:实际上,我调试了更多信息,尝试将 "strictPropertyInitialization": false 添加到您的编译器选项并检查。但它推翻了类型严格性(TS 的美丽特性)。但在我看来,不要这样做。更多info.

【讨论】:

  • 您可能会获得更多关于构造函数中的返回值如何在 JavaScript from MDN 中工作的信息。我认为 TypeScript 是 JavaScript 的超集。据我了解,这意味着我可以做到这一点并且它应该按原样工作。
【解决方案2】:

strictPropertyInitialization 强制您初始化所有在类的构造函数中不是可选的属性。此检查很有用,因为它可以确保您不会得到意外的未初始化属性。有几种方法可以解决这个错误,前两种是一般的方法,在你的情况下只有最后一种适用(为了完整性,我包括了所有):

初始化字段

如果将属性定义为boolean if 应该是truefalse 在声明字段或在构造函数中初始化时对其进行初始化:

class MyClass {
  someField: boolean = false;
  constructor() {
    return { someField: true };
  }
}

将该字段设为可选

如果字段可以是undefined,您应该在字段声明中使用? 或将字段键入为undefined|boolean 进行标记

class MyClass {
    //someField?: boolean;
    someField: boolean | undefined;
    constructor() {
        return { someField: true };
    }
}

使用非空断言

在你的情况下,因为在构造函数中你实际上没有初始化当前对象(this)而是返回一个新对象,你可以告诉编译器错误是错误的并使用非空断言。这个断言是专门引入的,因为strictPropertyInitialization 检查存在限制,有时编译器会出错。对于这些情况,您可以覆盖编译器的想法,但您必须明确说明:

class MyClass {
    someField!: boolean;
    constructor() {
        return { someField: true };
    }
}

【讨论】:

  • 这可能仍然会破坏instanceof
【解决方案3】:

解决方案 1

在名称后添加 (!) 符号:

someField!:string;

解决方案 2

打开 TypeScript 配置文件 tsconfig.json 并将此代码添加到编译器选项

 "angularCompilerOptions": {
    //   ...
    "strictPropertyInitialization": false
    //   ...
  }

注意:它会使静态分析变弱

【讨论】:

    【解决方案4】:
    "angularCompilerOptions": {
        //   ...
        "strictPropertyInitialization": false
        //   ...   }
    

    根据angular最新版本,它支持严格类型,所以你必须禁用它。

    进行修改并重新启动服务器

    【讨论】:

    • 这个问题与角度无关,也不涉及任何“服务器”
    • 请检查您自己的答案,并意识到代码中句子中超过 5% 的单词由单词“server”组成。恐怕除了投反对票之外,这个答案不会得到任何选票。
    • 强烈建议不要禁用严格检查。引入这些是有原因的。我建议我们阅读并了解它们被引入的原因并按照规则进行游戏。它将帮助您开发更好的软件
    猜你喜欢
    • 1970-01-01
    • 2021-06-23
    • 2021-04-13
    • 2021-05-21
    • 2021-05-06
    • 2021-08-14
    • 2021-02-28
    • 2021-09-04
    相关资源
    最近更新 更多