Archive

Writing Resilient TypeScript

Moving beyond 'any' and embracing the safety of advanced type narrowed utilities.

TypeScript is most effective when it is invisible. By leveraging type guards and exhaustive checks, we can make our systems impossible to represent in an invalid state.

type Shape =
  | { kind: 'circle'; radius: number }
  | { kind: 'square'; size: number };

function area(s: Shape) {
  switch (s.kind) {
    case 'circle': return Math.PI * s.radius ** 2;
    case 'square': return s.size ** 2;
    default: {
      const _exhaustive: never = s;
      return _exhaustive;
    }
  }
}

This pattern ensures that when you add a new shape, the compiler forces you to handle it everywhere.