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