///

TypeScript Exhaustive Switch with never Capsule

---

///

kind: capsule status: active visibility: private license: fair-use-summary summary: Discriminated union switch에서 default에 assertNever(x: never) 추가하면 새 variant 추가 시 컴파일 타임에 누락 감지. tags: - typescript - type-safety - pattern - capsule related: - personal_vault/knowledge/dev/typescript-advanced.md - personal_vault/projects/ops/librarian/capsules/TypeScript Practical Reference Capsule.md


TypeScript Exhaustive Switch with never Capsule

Core claim#

Discriminated union을 switch로 분기할 때, default 블록에서 never 타입으로 변수를 소비하는 헬퍼를 호출하면 union에 새 variant가 추가됐을 때 TypeScript가 컴파일 에러를 낸다 — 런타임 누락을 타입 시스템으로 잡는 패턴.

When to apply#

  • redux/zustand action union, API response discriminated union, state machine state
  • 도메인이 앞으로 확장될 가능성이 있고, 모든 consumer가 새 케이스를 처리해야 하는 경우

Recipe#

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number }
  | { kind: "triangle"; base: number; height: number };

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

function area(s: Shape): number {
  switch (s.kind) {
    case "circle":   return Math.PI * s.radius ** 2;
    case "square":   return s.side ** 2;
    case "triangle": return (s.base * s.height) / 2;
    default:         return assertNever(s);
    //                            ^? Argument of type 'Shape' is not assignable to 'never'
    //                                (when a new variant is added)
  }
}

동작 원리#

  • case가 narrow되어 default 블록에서 s의 타입은 never
  • 새 variant 추가 → default 블록의 s{ kind: "new"; ... } 타입이 됨
  • never 파라미터에 non-never를 넘기려 해서 TS 에러 TS2345

Caveats#

  • strictNullChecks 필수 (기본 strict 모드에 포함)
  • if/else if 체인에서도 동일 패턴 적용 가능 (마지막 else에 assertNever)
  • assertNever가 실제 throw하므로 런타임에서도 안전 — 하지만 도달하면 이미 런타임 버그

Source#

  • TypeScript Handbook "Discriminated Unions / Exhaustiveness checking": https://www.typescriptlang.org/docs/handbook/2/narrowing.html#exhaustiveness-checking
  • 공식 예제가 assertNever를 이 이름으로 소개함
  • 조회일: 2026-04-19

Sagwan Revalidation 2026-04-19T01:49:53Z#

  • verdict: ok
  • note: TypeScript exhaustive switch + assertNever 패턴은 TS 4.x~5.x 모두 동일하게 동작하며 현재도 표준 권장 방식이다.