#angular #typescript
Вопрос:
У меня есть следующий код:
тс:
get myArray(): any[]{
return [1,2,3];
}
шаблон:
<p>Test:</p>
<div *ngIf="myArray?.length > 2">
array has more than 2 items
</div>
Для этого компилятор сообщает мне:
Error in src/app/app.component.html (2:13)
Object is possibly 'undefined'.
Почему? Код работает просто отлично, если я напишу точно такое же выражение в компоненте:
constructor(){
if(this.myArray?.length > 2){
console.log("yay")
}
}
Пример стекблитца: https://stackblitz.com/edit/angular-ivy-hhpoag?file=src/app/app.component.ts
tsconfig:
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"strict": true,
"suppressImplicitAnyIndexErrors": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"module": "esnext",
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"typeRoots": ["node_modules/@types"],
"lib": ["es2018", "dom"]
},
"angularCompilerOptions": {
"enableIvy": true,
"fullTemplateTypeCheck": true,
"strictInjectionParameters": true,
"strictTemplates": true
}
}
Комментарии:
1. Похоже, что в .html (в строгом режиме) не разрешается сравнивать значение null или undefined с числом, которое вы можете использовать
*ngIf="myArray amp;amp; myArray.length>2"
.ПРИМЕЧАНИЕ: работает*ngIf mtArray?.length
, потому что это говорит «если существует, а не пусто».2. Не знаю, почему он ведет себя по-другому, но в шаблоне
?.
делает typeofmyArray?.length
number | undefined
. В компоненте?
не имеет значения, потому что тип возвращаемого значения не может быть нулевым (any[]
).3. Удалить
?
из*ngIf="myArray?.length > 2"
?4. Почему вам нужно
?.
всегда определенное значение?5. Угловой шаблон не оставляет шансов. А также с асинхронным каналом и наблюдаемыми объектами — вам не будет разрешено сравнивать результат с числом способом < или>, потому что необязательный параметр не определен или равен нулю. Комментарий @Eliseo, вероятно, лучший вариант.
Ответ №1:
Один из моих коллег указал на источник ошибки:
Механизм угловых шаблонов (вероятно) затмевает тип моего геттера. myArray
Тип будет изменен с any[]
на any[] | undefined
. Если мы это сделаем, код машинописи в компоненте также выйдет из строя:
import { Component } from '@angular/core';
import { FormArray, FormControl, FormGroup } from '@angular/forms';
@Component({
selector: 'my-app',
template: ``
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
get myArray(): any[] | undefined { // causes build time error too without a template
return [1,2,3];
}
constructor(){
if(this.myArray?.length > 2){
console.log("yay")
}
}
}
Одно из возможных решений-проверить значение и при необходимости заменить его, как это показано в шаблоне:
<p>Test:</p>
<div *ngIf="(myArray?.length ?? 0) > 2">
array has more than 2 items
</div>
Стекблитц: https://stackblitz.com/edit/angular-ivy-muwdqu?file=src/app/app.component.html