Décrivez le bogue
Lorsque le composant utilise une fonction qui retourne un prédicat de type (type guard), l'éditeur affiche une erreur liée à un champ manquant, même si le champ est là et que le code compile (Angular v8.2).
Reproduire
Utilisez un type guard dans *ngIf
. Essayez d'utiliser un champ de l'interface qui est déterminé par celui-ci dans des éléments imbriqués.
// 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
Comportement prévisible
Il n'y a pas d'erreur dans l'éditeur.
de même, les gardes de type ne s'appliquent pas aux contextes dans le service de langage (ils semblent s'appliquer lors de la compilation exactement comme cela)
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>
Dans le type de service de langue (survolez l'info-bulle dans vscode sur item
intérieur de {{ }}
au moins) est any
Lors de la compilation, le type est correctement ExampleValue
C'est quelque chose qui sera corrigé dans le prochain service de langue Ivy-native (voir https://github.com/angular/vscode-ng-language-service/issues/335#issuecomment-693545000), mais pas quelque chose que nous prévoyons de corriger avant cette date en raison des limitations inhérentes à la mise en œuvre actuelle du service linguistique.
Comme Ayaz l'a mentionné, cela est résolu dans le nouveau service linguistique qui a été publié dans la v11.1 en tant qu'opt-in. Vous pouvez l'activer dans les paramètres de l'extension :