财产' ...'没有初始化程序,并且在构造函数中没有明确赋值

时间:2018-04-06 18:33:21

标签: javascript angular typescript

在我的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);
  }
}

但在#34;使"财产我有一个错误。 我不知道该怎么办......

mistake

19 个答案:

答案 0 :(得分:44)

只需转到 tsconfig.json 并设置

即可
"strictPropertyInitialization": false

摆脱编译错误。

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

答案 1 :(得分:28)

转到您的 #define egcd(a, b, c, d) 2 文件并更改 tsconfig.json then"noImplicitReturns": false 添加到 "strictPropertyInitialization": false 属性下的 tsconfig.json 文件中。 这是我的 "compilerOptions" 文件的样子

tsconfig.json

tsconfig.json
<块引用>

希望这会有所帮助!! 祝你好运

答案 2 :(得分:20)

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

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

实际上,编译器会抱怨成员变量在使用前未定义。

对于在编译时未定义的成员变量的示例,具有@Input指令的成员变量:

@Input() userId: string;

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

@Input() userId?: string;

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

if (this.userId) {
} else {
}

相反,知道此成员变量的值将及时定义,也就是说,将在使用前定义它,我们可以告诉编译器不要担心未定义它。

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

@Input() userId!: string;

现在,编译器了解到,尽管未在编译时定义此变量,但应在运行时以及使用它之前及时定义该变量。

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

作为附加保护,我们可以在使用变量之前声明该变量已定义。

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

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

知道该变量已定义,就可以使用该变量:

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

请注意,ngOnInit方法是在尝试进行输入绑定之后调用的,即使没有为绑定提供实际的输入。

只有在有实际的输入提供给绑定之后,ngOnChanges方法才会被尝试进行输入绑定。

答案 3 :(得分:20)

我认为您使用的是最新版本的TypeScript。请参阅 link 中的“严格类初始化”部分。

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

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

B中。只需在构造函数中声明它时初始化数组,

makes: any[] = [];

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

答案 4 :(得分:18)

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

makes!: any[];

答案 5 :(得分:13)

2021 年更新:

<块引用>

有像“strictPropertyInitialization”这样的属性

只需转到 tsconfig.json 并设置

“严格”:假

摆脱编译错误。

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

这个错误背后的原因是:

  • 与 javascript 相比,typescript 是一种更安全的语言。
  • 虽然通过启用严格功能增强了这种安全性。所以每次初始化变量时,打字稿都希望它们分配一个值。

答案 6 :(得分:7)

在我的 Angular 项目中添加 Node 时出现此错误 -

<块引用>

TSError: ?无法编译打字稿: (路径)/base.api.ts:19:13 - 错误 TS2564:属性 'apiRoot Path' 没有初始化器,也没有在构造函数中明确赋值。

私有apiRootPath:字符串;

解决方案 -

tsconfig.json 的 'compilerOptions' 中添加了 "strictPropertyInitialization": false

我的package.json -

"dependencies": {
    ...
    "@angular/common": "~10.1.3",
    "@types/express": "^4.17.9",
    "express": "^4.17.1",
    ...
}

参考网址 - https://www.ryadel.com/en/ts2564-ts-property-has-no-initializer-typescript-error-fix-visual-studio-2017-vs2017/

答案 7 :(得分:6)

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

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

  • "strictPropertyInitialization": true添加到您的tsconfig.json

  • 如果您对禁用它不满意,也可以尝试使用此makes: any[] | undefined。为此,您需要使用null检查(?.)运算符(即this.makes?.length

  • )访问属性
  • 您还可以尝试使用makes!: any[];,它告诉TS该值将在运行时分配。

答案 8 :(得分:6)

如果您想初始化一个基于接口的对象,您可以使用以下语句将其初始化为空。

myObj: IMyObject = {} as IMyObject;

答案 9 :(得分:4)

您需要禁用--strictPropertyInitialization Sajeetharan提到或做了类似的事情以满足初始化要求:

makes: any[] = [];

答案 10 :(得分:3)

您不能只使用确定分配声明吗? (请参见https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#definite-assignment-assertions

即将属性声明为 $VstsBaseRestUrl = "$(System.TeamFoundationCollectionUri)" $projectsUrl = "$VstsBaseRestUrl/_apis/projects/${{ parameters.project }}?api-version=5.1" $rawResponse = Invoke-WebRequest -UseDefaultCredentials -Uri $projectsUrl -Method Get -ContentType "application/json" -Headers @{ Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN" } !确保打字稿在运行时肯定会有值。

抱歉,我还没有尝试过这种方法,但是当我在React中遇到完全相同的问题时,它对我来说非常有用。

答案 11 :(得分:2)

错误是合法,并且可能导致您的应用崩溃。您输入了makes作为数组,但是也可以不确定。

您有2个选项(而不是禁用打字稿存在的理由...):

1。。对于您而言,最好的方法是输入makes(可能未定义)。

makes?: any[]
// or
makes: any[] | undefined

在这种情况下,每当您尝试访问makes时,编译器都会通知您它可能是未定义的。 例如,如果您在// <-- Not ok完成之前写下面的getMakes行,或者如果getMakes失败,则会抛出编译错误。否则您的应用程序将崩溃。

makes[0] // <-- Not ok
makes.map(...) // <-- Not ok

if (makes) makes[0] // <-- Ok
makes?.[0] // <-- Ok
(makes ?? []).map(...) // <-- Ok

2。。您可以通过编写下面的代码(风险!)来假定它永远不会失败,并且您永远不会在初始化之前尝试访问它。因此编译器不会理会它。

makes!: any[]

答案 12 :(得分:2)

在变量必须保持未初始化(并且在运行时处理)的情况下修复的另一种方法是将 undefined 添加到类型(这实际上是 VC Code 建议的)。示例:

@Input() availableData: HierarchyItem[] | undefined;
@Input() checkableSettings: CheckableSettings | undefined;

根据实际使用情况,这可能会导致其他问题,所以我认为最好的方法是尽可能初始化属性。

答案 13 :(得分:0)

更改

fieldname?: any[]; 

对此:

fieldname?: any; 

答案 14 :(得分:0)

使用typescript@2.9.2进行升级时,其编译器严格遵守在组件类构造函数中声明数组类型的规则。

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

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

答案 15 :(得分:0)

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

makes: any[] | undefined;

答案 16 :(得分:0)

您可以像这样在构造函数中声明属性:

export class Test {
constructor(myText:string) {
this.myText= myText;
} 

myText: string ;
}

答案 17 :(得分:-1)

在变量“?”旁边你可以把它修好。

示例:

--------->id?:number --------->name?:string

答案 18 :(得分:-1)

我使用的是泛型类型并面临同样的问题以及我无法初始化属性的问题,因为它是泛型的,它可以是任何类型

class HoldAnything<TypeOfData>{
  data:TypeOfData;
 
}

const holdNumber = new HoldAnything<number>();
holdNumber.data =123;

const holdString = new HoldAnything<string>()
holdString.data="arvind";

为此,我将 tsconfig.json 文件中的 strictPropertyInitialization 设为 false。

从这里得到澄清Strict Class Initialization