Discriminated Union With Exhaustive Switch

Model variants as a union of objects sharing a literal tag and use a never-checked default to guarantee every case is handled.

TypescriptData Integrity

Code

snippet
export type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "rect"; width: number; height: number }
  | { kind: "triangle"; base: number; height: number };

export function area(shape: Shape): number {
  switch (shape.kind) {
    case "circle":
      return Math.PI * shape.radius ** 2;
    case "rect":
      return shape.width * shape.height;
    case "triangle":
      return (shape.base * shape.height) / 2;
    default: {
      const unreachable: never = shape;
      throw new Error("unhandled shape: " + JSON.stringify(unreachable));
    }
  }
}