Ми можемо отримати повідомлення Property has no initializer and is not definitely assigned in the constructor
при додаванні певної конфігурації у tsconfig.json
файл, щоб проект Angular був скомпільований у строгому режимі:
"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
метод викликається після спроби введення прив'язок, і лише якщо для прив'язок був наданий фактичний вхід.