Javascript 属性 '...' 没有初始值设定项,并且在构造函数中没有明确分配

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49699067/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:27:08  来源:igfitidea点击:

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

javascriptangulartypescript

提问by Michael Kostiuchenko

in my Angular app i have a component:

在我的 Angular 应用程序中,我有一个组件:

import { MakeService } from './../../services/make.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-vehicle-form',
  templateUrl: './vehicle-form.component.html',
  styleUrls: ['./vehicle-form.component.css']
})
export class VehicleFormComponent implements OnInit {
  makes: any[];
  vehicle = {};

  constructor(private makeService: MakeService) { }

  ngOnInit() {
    this.makeService.getMakes().subscribe(makes => { this.makes = makes
      console.log("MAKES", this.makes);
    });
  }

  onMakeChange(){
    console.log("VEHICLE", this.vehicle);
  }
}

but in the "makes" property I have a mistake. I dont know what to do with it...

但是在“makes”属性中我有一个错误。我不知道该怎么办...

mistake

错误

采纳答案by Sajeetharan

I think you are using the latest version of TypeScript. Please see the section "Strict Class Initialization" in the link.

我认为您使用的是最新版本的 TypeScript。请参阅link.

There are two ways to fix this:

有两种方法可以解决这个问题:

A. If you are using VSCode you need to change the TS version that the editor use.

A. 如果您使用的是 VSCode,则需要更改编辑器使用的 TS 版本。

B. Just initialize the array when you declare it inside the constructor,

B. 只需在构造函数中声明数组时对其进行初始化,

makes: any[] = [];

constructor(private makeService: MakeService) { 
   // Initialization inside the constructor
   this.makes = [];
}

回答by Martin ?uka

Just go to tsconfig.jsonand set

只需转到tsconfig.json并设置

"strictPropertyInitialization": false

to get rid of the compilation error.

摆脱编译错误。

Otherwise you need to initialize all your variables which is a little bit annoying

否则你需要初始化所有的变量,这有点烦人

回答by Harinath

It is because TypeScript 2.7 includes a strict class checking where all the properties should be initialized in the constructor. A workaround is to add the !as a postfix to the variable name:

这是因为 TypeScript 2.7 包含严格的类检查,所有属性都应在构造函数中初始化。一种解决方法是将!作为后缀添加到变量名称中:

makes!: any[];

回答by kshetline

You're either need to disable the --strictPropertyInitializationthat Sajeetharan referred to, or do something like this to satisfy the initialization requirement:

您要么需要禁用--strictPropertyInitializationSajeetharan 提到的那个,要么做这样的事情来满足初始化要求:

makes: any[] = [];

回答by SpeedOfSpin

You can also do the following if you really don't want to initialise it.

如果您真的不想初始化它,也可以执行以下操作。

makes: any[] | undefined;

回答by Stephane

We can get the message Property has no initializer and is not definitely assigned in the constructorwhen adding some configuration in the tsconfig.jsonfile so as to have an Angular project compiled in strict mode:

Property has no initializer and is not definitely assigned in the constructortsconfig.json文件中添加一些配置以便在严格模式下编译 Angular 项目时,我们可以得到消息:

"compilerOptions": {
  "strict": true,
  "noImplicitAny": true,
  "noImplicitThis": true,
  "alwaysStrict": true,
  "strictNullChecks": true,
  "strictFunctionTypes": true,
  "strictPropertyInitialization": true,

The compiler then complains that a member variable having an @Inputdirective is not defined before being used:

然后编译器会抱怨@Input在使用之前没有定义具有指令的成员变量:

@Input() userId: string;

We could silence the compiler by stating the variable may be optional:

我们可以通过声明变量可能是可选的来使编译器静音:

@Input() userId?: string;

But then, we would have to deal with the case of the variable not being defined, and clutter the source code with some such statements:

但是,我们将不得不处理未定义变量的情况,并用一些这样的语句来弄乱源代码:

if (this.userId) {
} else {
}

Instead, knowing the value of this member variable would be defined in time, that is, it would be defined before being used, we can tell the compiler not to worry about it not being defined.

相反,知道这个成员变量的值会被及时定义,也就是在使用之前已经定义,我们可以告诉编译器不要担心它没有被定义。

The way to tell this to the compiler is to add the ! definite assignment assertionoperator, as in:

告诉编译器的方法是添加! definite assignment assertion运算符,如下所示:

@Input() userId!: string;

Now, the compiler understands that this variable, although not defined at compile time, shall be defined at run-time, and in time, before it is being used.

现在,编译器明白这个变量虽然没有在编译时定义,但应该在运行时定义,并且在使用之前及时定义。

It is now up to the application to ensure this variable is defined before being used.

现在由应用程序来确保在使用之前定义此变量。

As an an added protection, we can assert the variable is being defined, before we use it.

作为额外的保护,我们可以在使用变量之前断言它正在被定义。

We can assert the variable is defined, that is, the required input binding was actually provided by the calling context:

我们可以断言变量已定义,即所需的输入绑定实际上是由调用上下文提供的:

private assertInputsProvided(): void {
  if (!this.userId) {
    throw (new Error("The required input [userId] was not provided"));
  }
}

public ngOnInit(): void {
  // Ensure the input bindings are actually provided at run-time
  this.assertInputsProvided();
}

Knowing the variable was defined, the variable can now be used:

知道变量已定义,现在可以使用变量:

ngOnChanges() {
  this.userService.get(this.userId)
    .subscribe(user => {
      this.update(user.confirmedEmail);
    });
}

Note that the ngOnInitmethod is called after the input bindings attempt, this, even if no actual input was provided to the bindings.

请注意,该ngOnInit方法在输入绑定尝试之后调用,即使没有向绑定提供实际输入。

Whereas the ngOnChangesmethod is called after the input bindings attempt, and only if there was actual input provided to the bindings.

而在ngOnChanges输入绑定尝试之后调用该方法,并且仅当有实际输入提供给绑定时才调用。

回答by Andy

Can't you just use a Definite Assignment Assertion? (See https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#definite-assignment-assertions)

你不能只使用一个明确的赋值断言吗?(见https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#define-assignment-assertions

i.e. declaring the property as makes!: any[];The ! assures typescript that there definitely will be a value at runtime.

即声明该属性为makes!: any[];The !确保打字稿在运行时肯定会有一个值。

Sorry I haven't tried this in angular but it worked great for me when I was having the exact same problem in React.

抱歉,我还没有在 angular 中尝试过这个,但是当我在 React 中遇到完全相同的问题时,它对我来说效果很好。

回答by Jai Govind Gupta

When you upgrade using [email protected] , its compiler strict the rules follows for array type declare inside the component class constructor.

当您使用 [email protected] 升级时,它的编译器严格遵循在组件类构造函数中声明数组类型的规则。

For fix this issue either change the code where are declared in the code or avoid to compiler to add property "strictPropertyInitialization": falsein the "tsconfig.json"file and run again npm start .

要解决此问题,请更改代码中声明的代码或避免编译器在“tsconfig.json”文件中添加属性“strictPropertyInitialization”: false并再次运行 npm start 。

Angular web and mobile Application Development you can go to www.jtechweb.in

Angular Web 和移动应用程序开发,您可以访问 www.jtechweb.in

回答by codejockie

As of TypeScript 2.7.2, you are required to initialise a property in the constructor if it was not assigned to at the point of declaration.

从 TypeScript 2.7.2 开始,如果在声明时未分配属性,则需要在构造函数中初始化该属性。

If you are coming from Vue, you can try the following:

如果您来自 Vue,则可以尝试以下操作:

  • Add "strictPropertyInitialization": trueto your tsconfig.json

  • If you are unhappy with disabling it you could also this makes: any[] | undefined. Doing this requires that you access the properties with null check (?.) operator i.e. this.makes?.length

  • You could as well try makes!: any[];, this tells TS that the value will be assigned at runtime.
  • 添加"strictPropertyInitialization": true到您的 tsconfig.json

  • 如果您对禁用它不满意,您也可以这样做makes: any[] | undefined。这样做需要您使用空检查 ( ?.) 运算符访问属性,即this.makes?.length

  • 您也可以尝试makes!: any[];,这告诉 TS 将在运行时分配该值。