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