Vscode-ng-language-service: 嵌套元素中无法识别类型保护

创建于 2020-08-04  ·  3评论  ·  资料来源: angular/vscode-ng-language-service

描述错误

当组件使用返回类型谓词(类型保护)的函数时,编辑器会显示与缺失字段相关的错误,即使该字段存在并且代码确实编译(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


预期行为

编辑器中没有错误。

bug ivy

所有3条评论

类似的类型保护不适用于语言服务中的上下文(它们似乎在编译时确实适用)

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 中作为选择加入发布的新语言服务中得到解决。 您可以在扩展设置中启用它:
image

此页面是否有帮助?
0 / 5 - 0 等级