Ми можемо отримати повідомлення 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метод викликається після спроби введення прив'язок, і лише якщо для прив'язок був наданий фактичний вхід.