简体   繁体   English

在Typescript 2.7中进行严格的类初始化

[英]Strict Class Initialization in Typescript 2.7

So I created a sample project using the Visual Studio 2017 template 'ASP.NET Core Web Application' with Angular. 因此,我使用带有Angular的Visual Studio 2017模板“ASP.NET Core Web Application”创建了一个示例项目。 I updated the package.json created by default to the latest modules' versions. 我将默认创建的package.json更新为最新模块的版本。 After running the npm install command and launching the site I get and error related to TypeScript. 运行npm install命令并启动站点后,我得到了与TypeScript相关的错误。

ERROR in [at-loader] ./ClientApp/app/components/fetchdata/fetchdata.component.ts:9:12 TS2564: Property 'forecasts' has no initializer and is not definitely assigned in the constructor. [at-loader]中的错误./ClientApp/app/components/fetchdata/fetchdata.component.ts:9:12 TS2564:属性'forecast'没有初始化程序,并且在构造函数中没有明确赋值。

Angular is running in the development mode. Angular正在开发模式下运行。 Call enableProdMode() to enable the production mode. 调用enableProdMode()以启用生产模式。 client.js:67 [HMR] connected client.js:160 [HMR] bundle has 1 errors client.js:161 [at-loader] ./ClientApp/app/components/fetchdata/fetchdata.component.ts:9:12 TS2564: Property 'forecasts' has no initializer and is not definitely assigned in the constructor. client.js:67 [HMR]连接client.js:160 [HMR]包有1个错误client.js:161 [at-loader] ./ClientApp/app/components/fetchdata/fetchdata.component.ts:9:12 TS2564:属性'forecast'没有初始值设定项,并且在构造函数中没有明确赋值。

The error is quite clear. 错误很清楚。 I researched a little bit and found out a new feature for the TS 2.7: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html 我研究了一下,发现了TS 2.7的一个新功能: https//www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html

Strict Class Initialization 严格的类初始化

TypeScript 2.7 introduces a new flag called --strictPropertyInitialization. TypeScript 2.7引入了一个名为--strictPropertyInitialization的新标志。 This flag performs checks to ensure that each instance property of a class gets initialized in the constructor body, or by a property initializer. 此标志执行检查以确保类的每个实例属性在构造函数体中初始化,或者由属性初始值设定项初始化。 For example ... 例如 ...

This is the code where the error appears 这是出现错误的代码

import { Component, Inject } from '@angular/core';
import { Http } from '@angular/http';

@Component({
    selector: 'fetchdata',
    templateUrl: './fetchdata.component.html'
})
export class FetchDataComponent {
    public forecasts: WeatherForecast[];

    constructor(http: Http, @Inject('BASE_URL') baseUrl: string) {
        http.get(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
            this.forecasts = result.json() as WeatherForecast[];
        }, error => console.error(error));
    }
}

interface WeatherForecast {
    dateFormatted: string;
    temperatureC: number;
    temperatureF: number;
    summary: string;
}

And this is my tsconfig.json file 这是我的tsconfig.json文件

{
  "compilerOptions": {
    "module": "es2015",
    "moduleResolution": "node",
    "target": "es5",
    "sourceMap": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "skipDefaultLibCheck": true,
    //"skipLibCheck": true, // Workaround for https://github.com/angular/angular/issues/17863. Remove this if you upgrade to a fixed version of Angular.
    "strictPropertyInitialization": false,
    "strict": false,
    "lib": [ "es6", "dom" ],
    "types": [ "webpack-env" ]
  },
  "exclude": [ "bin", "node_modules" ],
  "atom": { "rewriteTsconfig": false }
}

Then the VS intellisense doesn't complain but the error is still there when running. 然后VS intellisense没有抱怨,但运行时错误仍然存​​在。

I have also tried to define the forecasts field with public forecasts: WeatherForecast[]; 我还试图用public forecasts: WeatherForecast[];来定义forecasts字段public forecasts: WeatherForecast[]; but it didn't help 但它没有帮助

Node v9.9.0 TypeScript 2.7.2 Angular 5.2.9 节点 v9.9.0 TypeScript 2.7.2 Angular 5.2.9

You should define the field as being optional, as there will be a time interval between the constructor call and until you get the result of get that the field will be null . 你应该定义字段为可选的,因为会有构造函数调用之间的时间间隔,直到你得到的结果get了场将是null This does mean you will have to check that the field is not null where you use the field, but this is probably a good idea: 这意味着您必须检查该字段在您使用该字段时不为空,但这可能是一个好主意:

export class FetchDataComponent {
    public forecasts?: WeatherForecast[];
    // equivalent to: 
    // public forecasts: WeatherForecast[] | undefined;
    doStuff(){
        this.forecasts.push() // error Object is possibly 'undefined'
        if(this.forecasts != null) {
            this.forecasts.push(); // ok 
        }
        this.forecasts!.push() // We tell the compiler we know better and not to complain about Object is possibly 'undefined'
    }
}

Another option is to use the definite assignment assertion ( ! ) which will tell the compiler the field will be initialized and will definitely not be null (a lie in this case). 另一种选择是使用明确赋值断言( ! ),它将告诉编译器字段将被初始化并且绝对不会为null (在这种情况下是谎言)。 This exposes you to some runtime errors, but you will not need to check the fields on usage. 这会使您遇到一些运行时错误,但您无需检查使用情况字段。 I don't recommend this in this case, but it is your call: 在这种情况下我不推荐这个,但这是你的电话:

export class FetchDataComponent {
    public forecasts!: WeatherForecast[];
    doStuff(){
        this.forecasts.push() // ok
        if(this.forecasts != null) {
            this.forecasts.push(); // ok too
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM