type Payment =
| { kind: "card"; last4: string }
| { kind: "bank"; iban: string }
| { kind: "wallet"; id: string };
function assertNever(x: never): never { throw new Error("Unhandled: " + JSON.stringify(x)); }
function label(p: Payment): string {
switch (p.kind) {
case "card": return "Card " + p.last4;
case "bank": return "Bank " + p.iban;
default: return assertNever(p);
}
}
A compile error at
assertNever(p): the wallet type is not assignable to neverIt is a compile error at assertNever(p). After the two cases, TypeScript narrows p to the cases that are left. Before, nothing was left, so p was never. Now the wallet type is left, and it can't be passed as never. This is an exhaustive check: the compiler lists every place to update.
"It compiles, and wallet payments throw at runtime" would happen only without the never parameter type. The throw is just a safety net for bad data at runtime.