描述错误
当组件使用返回类型谓词(类型保护)的函数时,编辑器会显示与缺失字段相关的错误,即使该字段存在并且代码确实编译(Angular v8.2)。
再现
在*ngIf
使用类型保护。 尝试使用界面中由它在嵌套元素中确定的字段。
// my-model.model.ts
type MyModel = (MyModelA | MyModelB) & { type: 'A' | 'B' };
interface MyModelA {
fieldA: any;
}
interface MyModelB {
fieldB: any;
}
// foo.component.ts
public model: MyModel;
public isModelA(model): model is MyModelA {
return model.type === 'A';
}
// foo.component.html
md5-1956e8def7f34e35cec69338ae3e15c2
预期行为
编辑器中没有错误。
类似的类型保护不适用于语言服务中的上下文(它们似乎在编译时确实适用)
export class NgLetContext<T = any> {
// allows syntax "foo; let bar"
$implicit: T = null!;
// allows syntax "foo as bar"
ngLet: T = null!;
}
@Directive({
selector: '[ngLet]',
})
export class NgLetDirective<T> implements OnInit {
@Input()
set ngLet(value: T) {
this.context.$implicit = this.context.ngLet = value;
}
constructor(private containerRef: ViewContainerRef, private templateRef: TemplateRef<NgLetContext>) {}
private context = new NgLetContext<T>();
static ngTemplateContextGuard<T>(dir: NgLetDirective<T>, ctx: unknown): ctx is NgLetContext<T> {
return true;
}
ngOnInit() {
this.containerRef.createEmbeddedView(this.templateRef, this.context);
}
}
interface MyModel { baz: ExampleValue }
// foo.component.ts
public model: MyModel;
<div *ngLet="model.baz as item">
{{ item }}
</div>
在语言服务类型中(至少将 vscode 中的工具提示悬停在item
内的{{ }}
上)是any
编译时,类型正确ExampleValue
这将在即将推出的 Ivy 本地语言服务中修复(参见 https://github.com/angular/vscode-ng-language-service/issues/335#issuecomment-693545000),但不是我们计划的由于当前语言服务实现的固有限制,在此之前修复。
正如 Ayaz 所提到的,这已在 v11.1 中作为选择加入发布的新语言服务中得到解决。 您可以在扩展设置中启用它: