Typescript 2.7 中的严格类初始化

blf*_*tes 6 asp.net typescript asp.net-core angular

因此,我使用 Visual Studio 2017 模板“ASP.NET Core Web 应用程序”和 Angular 创建了一个示例项目。我将默认创建的 package.json 更新为最新模块的版本。运行npm install命令并启动站点后,我收到与 TypeScript 相关的错误。

[at-loader] ./ClientApp/app/components/fetchdata/fetchdata.component.ts:9:12 TS2564 中出现错误:属性“forecasts”没有初始值设定项,并且未在构造函数中明确分配。

Angular 正在开发模式下运行。调用enableProdMode()启用生产模式。client.js:67 [HMR] 已连接 client.js:160 [HMR] 捆绑包有 1 个错误 client.js:161 [at-loader] ./ClientApp/app/components/fetchdata/fetchdata.component.ts:9:12 TS2564:属性“预测”没有初始值设定项,并且未在构造函数中明确分配。

这个错误是很明显的。我做了一些研究,发现了 TS 2.7 的一个新功能: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html

严格的类初始化

TypeScript 2.7 引入了一个名为 --strictPropertyInitialization 的新标志。此标志执行检查以确保类的每个实例属性在构造函数主体中或通过属性初始值设定项进行初始化。例如 ...

这是出现错误的代码

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;
}
Run Code Online (Sandbox Code Playgroud)

这是我的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 }
}
Run Code Online (Sandbox Code Playgroud)

然后 VS 智能感知不会抱怨,但运行时错误仍然存​​在。

我也尝试过定义该forecasts字段public forecasts: WeatherForecast[];,但没有帮助

节点v9.9.0 TypeScript 2.7.2 Angular 5.2.9

Tit*_*mir 5

get您应该将该字段定义为可选字段,因为在构造函数调用和获得该字段的结果之间会有一个时间间隔null。这确实意味着您必须在使用该字段时检查该字段是否不为空,但这可能是一个好主意:

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'
    }
}
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用明确赋值断言 ( !),它会告诉编译器该字段将被初始化并且绝对不会被初始化null(在本例中是一个谎言)。这会让您遇到一些运行时错误,但您不需要检查使用情况的字段。在这种情况下我不建议这样做,但这是你的决定:

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