TypeScript

Discriminated Unions with Exhaustive Switch

admin by @admin ADMIN
1h ago
May 31, 2026
Public
0 0 up · 0 down Sign in to vote
Discriminated (tagged) unions give you compiler-checked state machines. Pair with `assertNever` to force every new variant to be handled at every switch site — refactors stop being scary.
TypeScript
Raw
type AsyncState<T> =
  | { status: 'idle' }
  | { status: 'loading' }
  | { status: 'success'; data: T }
  | { status: 'error';   error: Error };

function assertNever(x: never): never {
  throw new Error(`Unhandled variant: ${JSON.stringify(x)}`);
}

function render<T>(s: AsyncState<T>): string {
  switch (s.status) {
    case 'idle':    return '—';
    case 'loading': return 'Loading…';
    case 'success': return `OK: ${JSON.stringify(s.data)}`;
    case 'error':   return `Error: ${s.error.message}`;
    default:        return assertNever(s);   // ← compile error if you add a variant
  }
}
Tags

Save your own code snippets

Create a free account and build your private vault. Share publicly whenever you want.