Angularプロジェクトを厳密モードでコンパイルするためProperty has no initializer and is not definitely assigned in the constructor
に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 {
this.assertInputsProvided();
}
変数が定義されていることがわかったので、変数を使用できるようになりました。
ngOnChanges() {
this.userService.get(this.userId)
.subscribe(user => {
this.update(user.confirmedEmail);
});
}
ngOnInit
バインディングに実際の入力が提供されていなくても、入力バインディングの試行後にメソッドが呼び出されることに注意してください。
一方、ngOnChanges
メソッドは入力バインディングの試行後に呼び出され、バインディングに実際の入力が提供された場合にのみ呼び出されます。