I have a template that looks like this (I'm using some component that uses this as the basis for a repeated item, it's the <p-pickList>, but the question is not specific about that component, just as an example)
For background, let's say I have a type Foo and my component has a foos: Foo[], I'm feeding it to the <p-pickList> component under the [source] attribute and its doing the internal *ngFor for it, all I have to do is provide a template
<ng-template let-foo pTemplate="item"> ... {{ foo.anythingGoesHereWithNoWarningAndNoAutocomplete }} However, the type information on foo seems to be lost.
I'm a big fan of type safety and I like that Intellij (or any other editor) can show me a warning if inside the template I do something like specifying an invalid attribute of foo
If I had a regular *ngFor, it would infer the type of foo
<div *ngFor="let foo of foos"> {{ foo.autoCompleteWorksInMostIDEsAsWellAsWarningIfInvalidProp }} Is there any syntax that will allow me to hint the type of let-foo? (and hopefully most IDE's will recognize).
If I don't want to rely on IDE's, is there a way to have the ng compiler type check foo (declared by let-foo)?
tl;dr is there a syntax that let me type annotate the template input variable? e.g. something like this made up syntax?
let-foo="$implicit as Foo" or let-foo-type="Foo"?
One silly idea is to have an identity function in my component, e.g.
identity(foo: Foo): Foo { return foo; } But doing
{{ identity(foo).fooProp }} Is not a big improvement over
{{ (foo as Foo).fooProp }}`
Use template variables to perform tasks such as respond to user input or finely tune your application's forms. A template variable can refer to the following: a DOM element within a template. a directive or component. a TemplateRef from an ng-template.
We declare Template reference variables using # followed by the name of the variable ( #variable ).
Let's see what angular has similar to that and how it work!
<p *ngFor="let number of [{v: 101},{v: 102}, {v: 103}]">{{number.v}}</p> We can rewrite it without * magic
<ng-template ngFor let-number [ngForOf]="[{v: 101},{v: 102}, {v: 103}]"> <p>{{number.v}}</p> </ng-template> Without watchers (ngDoCheck) it can be the same as (but ngTemplateOutlet have no typecheck):
<ng-template let-number #templateRef> <p>{{number.v}}</p> </ng-template> <ng-container *ngTemplateOutlet="templateRef; context: {$implicit: {v: 101}}"></ng-container> <ng-container *ngTemplateOutlet="templateRef; context: {$implicit: {v: 102}}"></ng-container> <ng-container *ngTemplateOutlet="templateRef; context: {$implicit: {v: 103}}"></ng-container> Or we can create it by ourselves
// template <button (click)=create(templateRef)>create</button> // TS constructor(private _viewContainerRef: ViewContainerRef) { ... } create(templateRef: TemplateRef<{$implicit: {v: number;}}>) { this._viewContainerRef.createEmbeddedView(templateRef, {$implicit: {v: 101}}); this._viewContainerRef.createEmbeddedView(templateRef, {$implicit: {v: 102}}); this._viewContainerRef.createEmbeddedView(templateRef, {$implicit: {v: 103}}); } TL;DR
Template typecheck magic happens inside viewContainerRef.createEmbeddedView. (for example ngFor); But it assume what templateRef accepts.
Angular can compile in AOT:
<p *ngFor="let num of [{v:1}, {v:2}]"> {{num.does.not.exist.completly}} </p> So as i understood we should assume what types templates have but do check when template is instantiated (by createEmbeddedView);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With