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);