`input.required<Severity, string>({ transform: toSeverity })` declares two distinct types for the same input: `string` is what a template author is allowed to bind (`[severity]="someString"`), while `Severity` is what the component body reads back via `severity()`. The `transform` function runs synchronously at binding time and is the only bridge between them — the compiler enforces that the transform's parameter type matches the write type and its return type matches the read type, so a mismatched transform fails to compile rather than silently letting an unvalidated string through. Because the input is `required`, TypeScript also refuses to compile any template that instantiates `AlertBannerComponent` without binding `severity`.
import { Component, input } from '@angular/core';type Severity = 'low' | 'medium' | 'high';function toSeverity(value: string): Severity {const normalized = value.toLowerCase();if (normalized === 'low' || normalized === 'medium' || normalized === 'high') {return normalized;}throw new Error(`Invalid severity value: "${value}"`);}@Component({selector: 'app-alert-banner',standalone: true,template: `<div [class]="'banner-' + severity()">{{ message() }}</div>`,})export class AlertBannerComponent {severity = input.required<Severity, string>({ transform: toSeverity });message = input.required<string>();}