전체 목록
TypeScriptMedium#132

Union 타입을 안전하게 좁히는 방법에는 무엇이 있나요?

#TS#Union#Narrowing#TypeGuard

답변 포인트

타입 가드와 판별 유니온를 기준으로 정의, 장점, 한계, 예시를 함께 설명해보세요.

정답 및 해설

빠른 요약

typeof, instanceof, in 연산자, 사용자 정의 타입 가드, discriminated union으로 타입을 좁힐 수 있습니다. 판별 필드를 두면 switch에서 누락 케이스를 never로 검증하기 좋습니다.

typeof, instanceof, in 연산자, 사용자 정의 타입 가드, discriminated union으로 타입을 좁힐 수 있습니다. 판별 필드를 두면 switch에서 누락 케이스를 never로 검증하기 좋습니다.

핵심 개념

핵심 기준은 타입 가드와 판별 유니온입니다. 이 개념은 단순한 용어가 아니라, 실제 코드나 시스템에서 반복적으로 생기는 문제를 다루기 위해 등장했습니다.

TypeScript는 런타임 전에 실수를 발견하고 코드의 의도를 타입으로 문서화하기 위해 사용합니다. 좋은 타입은 자동완성, 리팩터링, 협업 안정성을 높여줍니다.

동작 흐름

  1. 먼저 어떤 문제가 있는지 확인합니다.
  2. 이 개념이 그 문제를 어떤 기준으로 나누거나 해결하는지 봅니다.
  3. 실제 코드에서는 입력, 상태, 실행 순서, 비용이 어떻게 바뀌는지 확인합니다.
  4. 마지막으로 한계와 부작용을 함께 점검합니다.

실제 예시

TypeScript
type Result =
  | { status: "success"; data: string }
  | { status: "error"; message: string };

function render(result: Result) {
  switch (result.status) {
    case "success":
      return result.data;
    case "error":
      return result.message;
  }
}

판별 필드가 있으면 TypeScript가 분기마다 타입을 정확히 좁혀줍니다.

실무에서 주의할 점

  • 타입 단언으로 오류를 덮기보다 타입을 좁히는 코드를 먼저 고려합니다.
  • 런타임 검증이 필요한 외부 입력은 타입만으로 안전해지지 않습니다.
  • 공개 타입은 너무 구체적이어도, 너무 느슨해도 유지보수가 어려워집니다.

함께 연결해서 보면 좋은 키워드

TS, Union, Narrowing, TypeGuard

정리

한 줄로 정리하면, typeof, instanceof, in 연산자, 사용자 정의 타입 가드, discriminated union으로 타입을 좁힐 수 있습니다. 판별 필드를 두면 switch에서 누락 케이스를 never로 검증하기 좋습니다. 실무에서는 개념을 적용하는 조건과 적용하지 않았을 때 생기는 문제까지 함께 이해하는 것이 중요합니다.

Union 타입 좁히기 방법

Union 타입은 여러 가능성 중 하나이므로, 사용하기 전에 현재 값이 어떤 형태인지 좁혀야 합니다.

TypeScript
type Result =
  | { status: 'success'; data: string }
  | { status: 'error'; error: Error };

function render(result: Result) {
  if (result.status === 'success') {
    return result.data;
  }
  return result.error.message;
}

대표적인 narrowing 기법

  • typeof: primitive 타입 구분
  • instanceof: 클래스 인스턴스 구분
  • in: 속성 존재 여부 확인
  • discriminated union: 공통 판별 필드 사용
  • 사용자 정의 type guard
TypeScript
function isUser(value: unknown): value is { id: string; name: string } {
  return typeof value === 'object' && value !== null && 'id' in value && 'name' in value;
}

주의할 점

타입 단언(as)은 좁히기가 아니라 컴파일러에게 믿으라고 말하는 것입니다. 외부 입력(JSON, URL, localStorage)은 런타임 검증 없이 as로 처리하면 장애로 이어질 수 있습니다.

관련 질문

같은 카테고리/태그 기준