노트

판별 유니언

Discriminated Union

프런트엔드#ts · 연결된 개념 9개

쉽게 말하면

판별 유니언은 상태마다 'loading', 'success' 같은 이름표를 붙여 두는 타입이에요. 이름표만 확인하면 성공일 땐 데이터가, 실패일 땐 에러가 있다는 걸 TypeScript가 알아서, 로딩 중인데 데이터도 있는 이상한 조합이 사라져요.

비유가 깨지는 곳 이름표는 빠진 분기도 잡아 줘요. 새 상태를 추가하고 switch를 안 고치면 default의 never 대입에서 컴파일 에러가 나요. 같은 모양의 switch가 여러 곳에 반복되면 다형성을 검토해요.

판별 유니언(Discriminated Union)은 모든 멤버가 리터럴 타입의 공통 필드(구분자(discriminant), 보통 type·kind·status)를 가진 유니언이다. 그 필드를 검사하면 TypeScript가 나머지 속성까지 자동으로 좁혀 준다.

type State =
  | { status: 'loading' }
  | { status: 'success'; data: User[] }
  | { status: 'error'; error: Error }
 
function render(s: State) {
  switch (s.status) {
    case 'loading': return '로딩 중'
    case 'success': return s.data.length   // data 접근 가능
    case 'error':   return s.error.message
    default:
      const _exhaustive: never = s         // 철저성 검사
      return _exhaustive
  }
}
  • 불가능한 상태를 표현할 수 없게 만든다. { loading?: boolean; data?: User[]; error?: Error }는 "로딩 중인데 데이터도 있는" 이상한 조합을 허용한다. 판별 유니언은 가능한 상태만 적는다
  • 철저성 검사(Exhaustiveness Checking): 새 멤버({ status: 'empty' })를 추가하고 switch를 안 고치면 never에 대입할 수 없다는 컴파일 에러가 난다. 이렇게 빠진 분기를 빌드 단계에서 찾는다
  • React의 비동기 상태, 인증 훅 반환값, useReducer의 액션({ type: 'set'; payload: number })에 잘 맞는다
  • 같은 구조의 switch가 여러 곳에 반복되면 다형성이나 상태 패턴을 검토한다

좁히기 일반은 타입 좁히기와 타입 가드, 유니언 자체는 유니언·인터섹션·리터럴 타입.

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 템플릿 리터럴 타입

    템플릿 리터럴 타입(Template Literal Types)은 문자열 리터럴 타입을 템플릿 문자열 문법으로 조합해 새 문자열 유니언을 만드는 기능이다. 유니언을 넣으면 가능한 모든 조합이 나온다.

  • type과 interface

    type(타입 별칭, Type Alias)과 interface는 둘 다 타입에 이름을 붙이는 방법이다. 객체 모양을 정의할 때는 대부분 바꿔 써도 되지만, 확장 방식과 표현 범위가 다르다.

  • 유틸리티 타입

    유틸리티 타입(Utility Types)은 기존 타입에서 새 타입을 만들어 주는 TypeScript 내장 제네릭 타입이다. 같은 모양을 손으로 다시 선언하지 않게 해 준다.

  • 타입 추론과 타입 검사

    타입 추론(Type Inference)은 표기가 없어도 컴파일러가 값의 타입을 정하는 단계이고, 타입 검사(Type Checking)는 정해진(추론됐거나 명시된) 타입을 코드가 지키는지 확인하는 단계다. 보통 추론이 먼저 일어나고, 그 결과를 기준으로 검사한다.

  • React Testing Library

    React Testing Library(RTL)는 컴포넌트를 jsdom 같은 테스트용 DOM(Document Object Model) 환경에 렌더하고, 사용자가 실제로 쓰는 방식으로 요소를 찾고 조작하게 해 주는 테스트 도구다. 내부 구현(state, 메서드)이 아니라 화면에 보이는 동작을 검증하라는 철학을 강하게 가진 라이브러리다.

보기 옵션