Describe el error
Cuando el componente usa una función que devuelve un predicado de tipo (protección de tipo), el editor muestra un error relacionado con un campo faltante, aunque el campo está allí y el código se compila (Angular v8.2).
Reproducir
Utilice un protector de tipo en *ngIf
. Intente usar un campo de la interfaz que está determinado por él en elementos anidados.
// 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
Comportamiento esperado
No hay ningún error en el editor.
de manera similar, los guardias de tipo no se aplican a contextos en el servicio de idiomas (parecen aplicarse mientras se compilan, tal como lo hace esto)
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>
En el tipo de servicio de idioma (la información sobre herramientas flotante en vscode sobre item
dentro de {{ }}
al menos) es any
Al compilar, el tipo es correctamente ExampleValue
Esto es algo que se solucionará en el próximo servicio de idioma nativo de Ivy (consulte https://github.com/angular/vscode-ng-language-service/issues/335#issuecomment-693545000), pero no es algo que planeemos hacer corregir antes de esa fecha debido a las limitaciones inherentes de la implementación actual del servicio de idiomas.
Como mencionó Ayaz, esto se resuelve en el nuevo Servicio de idiomas que se lanzó en v11.1 como opción de suscripción. Puede habilitarlo en la configuración de la extensión: