CodePark/ questions / Polymorphism: classes vs unions
START PRACTICINGPRACTICE
Backend question · Object-oriented programming › Polymorphism: classes vs unions

A teammate adds { kind: "wallet"; id: string } to the Payment union but doesn't touch label. What happens?

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 never

It 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.