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>

言語サービスのタイプ (少なくとも{{ }}内のitem上に vscode でツールチップをホバーする) はany

コンパイル時、タイプは正しくExampleValue

これは、今後の Ivy ネイティブ言語サービスで修正される予定です (https://github.com/angular/vscode-ng-language-service/issues/335#issuecomment-693545000 を参照)。現在の言語サービスの実装に固有の制限があるため、それまでに修正してください。

Ayaz が述べたように、これは v11.1 でオプトインとしてリリースされた新しい言語サービスで解決されています。 拡張機能の設定で有効にすることができます。
image

このページは役に立ちましたか?
0 / 5 - 0 評価