Angular's structural directive context objects are untyped by default, so template consumers get no compile-time feedback when they misspell a context variable like `let-idx="indx"`. The `ngTemplateContextGuard` static method is a compiler hook Angular's template type-checker specifically looks for: it lets a generic directive assert the shape of its context object so the template compiler narrows and validates `let-` bindings against the real interface. Without this guard, the Ivy template checker falls back to `any` for the context, silently accepting broken bindings that only fail at runtime with 'undefined is not a function' deep in a loop.
import { Directive, TemplateRef, Input } from '@angular/core';export interface RowContext<T> {$implicit: T;index: number;isLast: boolean;}@Directive({selector: '[appRow]',standalone: true,})export class RowDirective<T> {@Input('appRow') data!: T;constructor(public template: TemplateRef<RowContext<T>>) {}static ngTemplateContextGuard<T>(dir: RowDirective<T>,ctx: unknown): ctx is RowContext<T> {return true;}}// usage in host component template:// <ng-container *ngFor="let item of items; let i = index; let last = last">// <ng-template [appRow]="item" let-row let-idx="index" let-isLast="isLast">// {{ row.name }} - {{ idx }} - {{ isLast }}// </ng-template>// </ng-container>