【问题标题】:Property has no initializer and is not definitely assigned in the constructor属性没有初始化器,也没有在构造函数中明确分配
【发布时间】:2021-02-28 14:35:35
【问题描述】:

我给的时候出错了

export class UserComponent implements OnInit {
user:User;
constructor(){
    
    
}

ngOnInit(){  

    this.user = {
        firstName : "test",
        lastName : "test",
        age : 40,
        address: {
            street : "Test",
            city : "test",
            state: "test"
        }
    }
    
  }

}

我收到此错误:

Property 'user' has no initializer and is not definitely assigned in the constructor.

user 继承自 User.ts,User.ts 包含以下代码:

export interface User {
firstName:string,
lastName:string,
age?:number,
address?:{
    street?: string,
    city?:string,
    state?:string
}


}

向用户添加? 在其他文件中显示错误:

还有另一个名为 users 的文件夹...这是主要的...现在我添加 ?在这里,它显示了这个错误。

【问题讨论】:

  • 好吧,它没有在构造函数中初始化或分配,是吗?您可以通过这样做而不是在 ngOnInit 中避免该错误。
  • 是的..但是在课程中,他们说构造函数用于注入依赖项..在构造函数中添加它们后,我仍然遇到第二个错误(在问题的图 2 中)
  • 我不知道你在做什么课程,但它不一定是独家。当turning on strict mode 时,我不得不从ngOnInit 切换到constructor,但所有测试仍然通过。并且不清楚您在最后两个屏幕截图中的预期 - 1. 在一个地方将其设为可选并不会使它在任何地方都是可选的;和 2. 如果它是可选的 users?.length is 可能未定义。
  • 哦...为什么users?.length 未定义?这里不想提课程名称..可能违反栈溢出规则
  • 可能未定义,因为如果 users 是可选的,则 users 可以未定义,在这种情况下 users?.length 也未定义。为什么要提及您从中获取信息的资源是个问题?

标签: angular typescript


【解决方案1】:

这是由 TypeScript 的严格类初始化引起的。

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#strict-class-initialization

要解决此问题,您必须声明类型既可以是 Foo|undefined,也可以使用“!”根据上述文档表示明确分配的符号:

案例一:

@Component({...})
export class Component {
  @Input() myInput: string|undefined;
}

我们指明类型可以是字符串也可以是未定义的。

案例 2:

@Component({...})
export class Component {
  @Input() myInput!: string;
}

在这种情况下,我们使用 !符号表示我们知道myInput 没有在构造函数中初始化,我们将在其他地方处理它。

替代解决方案

如果您不关心严格的类初始化,您可以在您的 tsconfig.json 中通过在编译器选项中添加一个标志来完全禁用该功能

{
 "compilerOptions": {
    "strictPropertyInitialization": false
  }
}

注意:您必须重新启动 TypeScript 服务器才能重新应用 compilerOptions。实现这一点的最简单方法是简单地重新启动 IDE。

【讨论】:

  • 即使我在写myInput = undefined 时使用了myInput!: string;,我也会收到错误提示undefined is not assignable to type
  • 对,当您使用! 时,这就像您做出的承诺,即该值不会是undefined,这就是为什么编译器认为将其分配为未定义是错误的。正确的用法是简单地编写 myInput!: string 并确保它在第一次使用之前保存一个字符串值,即使这是一个空字符串,例如 myInput = ""
  • 男人!我在这个问题上卡了 30 分钟,谢谢!
【解决方案2】:

我认为你的课程是正确的。但是,如果它们与渲染无关,我认为从 ngOnInit 中移动它们是最好的。

IMO,Angular 制定了一个快速规则来避免一些渲染问题,但它不是黑白的。我认为这条规则只是试图让新用户的事情变得简单。这是一个更高级的话题。

引用https://github.com/angular/angular/issues/24571#issuecomment-404606595

For angular components, use the following rules in deciding between:
a) adding initializer
b) make the field optional
c) leave the '!'

If the field is annotated with @input - Make the field optional b) or add an initializer a).
If the input is required for the component user - add an assertion in ngOnInit and apply c.
If the field is annotated @ViewChild, @ContentChild - Make the field optional b).
If the field is annotated with @ViewChildren or @ContentChildren - Add back '!' - c).
Fields that have an initializer, but it lives in ngOnInit. - Move the initializer to the constructor.
Fields that have an initializer, but it lives in ngOnInit and cannot be moved because it depends on other @input fields - Add back '!' - c).

我认为这是一个很好的指导方针

【讨论】:

    猜你喜欢
    • 2021-08-14
    • 2021-04-13
    • 2021-05-21
    • 2021-05-06
    • 2021-12-25
    相关资源
    最近更新 更多