Skip to lesson
Exit
Applied Coding & Editor Primitives1 / 3

1 min lesson

Exhaustive unions catch your bugs

Answer "Why add a const _exhaustive: never = node; default case to a switch over a discriminated union?" Use one lesson detail to support it.

Step 1 of 3

Exhaustive unions catch your bugslet the compiler do the work

When you model a file-system node or a parse result as a discriminated union, a switch on the discriminant plus a never default makes the compiler error the moment you add a variant and forget to handle it. This is free correctness and showing it signals you write code the type system protects.

Learn more

Full explanation

The never-default trick: compiler error if a case is unhandled

The never-default trick: compiler error if a case is unhandled.ts
function size(node: FsNode): number {
  switch (node.kind) {
    case 'file': return node.bytes.length;
    case 'dir':  return node.children.reduce((n, c) => n + size(c), 0);
    default: {
      const _exhaustive: never = node;  // new variant -> compile error here
      return _exhaustive;
    }
  }
}

Prove correctness fastlightweight tests beat claims

You won't wire up a full test runner in 45 minutes, but a handful of inline assertions proves your edge cases work and reads as a tester's instinct. Run the empty case, the single element and the one tricky case you're worried about.

Cheap inline checks you can run anywhere, no framework needed.ts
function assertEq<T>(got: T, want: T, msg: string): void {
  const a = JSON.stringify(got), b = JSON.stringify(want);
  if (a !== b) throw new Error(`${msg}: got ${a}, want ${b}`);
}

assertEq(findDuplicates([]), [], 'empty input');
assertEq(applyEdits('abc', [{ offset: 1, length: 1, text: 'X' }]), 'aXc', 'single edit');