[TYPESCRIPT] 유니온 타입(Union)과 교차 타입(Intersection) — TypeScript의 유연한 타입 설계 핵심

TypeScript의 진정한 힘은 타입을 조합하는 능력에 있습니다. 그중에서도 가장 중요한 개념이 바로 유니온 타입(Union)교차 타입(Intersection)입니다. 이 두 개념을 제대로 이해하면, 데이터 모델링부터 API 설계까지 훨씬 더 유연하고 견고한 타입을 구성할 수 있습니다.

 

유니온 타입(Union)이란?

유니온 타입은 둘 이상의 타입 중 하나를 허용하는 타입입니다. 쉽게 말해 “A 또는 B” 타입의 값을 담을 수 있습니다.

let value: string | number;

value = "hello";
value = 100;
// 둘 다 가능

유니온 타입은 서로 다른 타입이 들어올 수 있는 “여러 가능성”을 표현할 때 매우 유용합니다.

 

✔ 실무 예제 — API 응답

type ApiResponse = 
  | { success: true; data: any }
  | { success: false; error: string };

API 결과가 성공/실패 두 형태로 구분되므로 유니온 타입이 자연스럽게 사용됩니다.

 

✔ 타입 좁히기(Narrowing)와 함께 사용

유니온 타입은 조건문을 통해 좁혀서 안전하게 사용할 수 있습니다.

function printId(id: string | number) {
  if (typeof id === "string") {
    console.log(id.toUpperCase());
  } else {
    console.log(id.toFixed(2));
  }
}

유니온 타입이 강력한 이유는 바로 이 조건부 분기(타입 가드) 덕분입니다.

 

교차 타입(Intersection)이란?

교차 타입은 두 타입을 모두 만족하는 타입입니다. 즉 "A 그리고 B" 형태의 타입이며, 유니온과 상반된 개념입니다.

type A = { name: string };
type B = { age: number };

type C = A & B;

const person: C = {
  name: "Alice",
  age: 20
};

교차 타입은 객체 구조를 결합해야 하는 상황에서 매우 유용합니다.

 

✔ 실무 예제 — 사용자 + 권한 결합

type User = { id: number; name: string };
type Admin = { role: "admin" };

type AdminUser = User & Admin;

유저 정보와 관리자 권한을 합쳐 새로운 타입을 만들 때 자연스럽게 사용됩니다.

 

유니온 vs 교차 — 가장 중요한 차이

개념 유니온( | ) 교차( & )
의미 A 또는 B (하나만 만족) A 그리고 B (둘 다 만족)
형태 선택 가능한 타입 집합 모든 속성을 병합한 타입
사용 예 API 성공/실패 객체 구조 병합
타입 가드 필요 여부 필요 (가능성 여러 개) 필요 없음

 

유니온 + 태그(Discriminated Union) — 실무 최강 조합

복잡한 상태나 이벤트 구조를 설계할 때 가장 많이 쓰는 고급 패턴입니다.

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

function area(shape: Shape) {
  switch (shape.kind) {
    case "circle":
      return Math.PI * shape.radius ** 2;
    case "square":
      return shape.size ** 2;
  }
}

각 구조에 “kind”라는 태그를 붙여서 타입 좁히기를 단순화하는 패턴입니다. Redux, React Query, GraphQL 에서 매우 자주 사용됩니다.

 

교차 타입 주의사항 — 속성 충돌

교차 타입을 사용할 때 하나 주의해야 할 점은, 같은 속성이 서로 다른 타입을 갖고 있으면 충돌이 발생한다는 것입니다.

type A = { value: string };
type B = { value: number };

type C = A & B;
// C의 value는 string & number → never 타입

충돌하는 속성은 교집합이 존재하지 않기 때문에 never가 되며, 사실상 사용 불가능한 타입이 됩니다.

 

실무에서의 선택 기준

✔ 다음 경우에는 유니온을 사용

  • 서로 다른 타입 중 하나만 올 수 있는 상황
  • API 응답 구조 정의
  • 이벤트 타입 설계
  • 여러 상태 값 처리 (loading | success | error)

✔ 다음 경우에는 교차 타입을 사용

  • 객체 구조를 합칠 때
  • 여러 개의 설정/옵션을 함께 적용할 때
  • 기존 타입에 속성을 확장할 때
  • MVC, OOP 스타일에서 역할 결합

 

예제 — 유니온 + 교차 조합

두 개념은 단독으로도 강력하지만, 함께 사용하면 훨씬 더 유연한 타입 설계가 가능합니다.

type User = { id: number; name: string };
type Admin = { role: "admin" };
type Guest = { role: "guest" };

type Person = User & (Admin | Guest);

// Admin 사용자 또는 Guest 사용자

이 패턴은 RBAC(Role Based Access Control) 설계에서 많이 사용됩니다.

 


 

유니온 타입과 교차 타입은 TypeScript를 “타입 시스템이 강력한 언어”로 만들어주는 핵심 도구입니다. 이 두 개념을 정확히 이해하면, 객체 디자인부터 상태 관리, API 모델링까지 복잡한 구조를 안정적이고 명확하게 표현할 수 있습니다.

  • 유니온( | ) → 여러 가능성 중 하나
  • 교차( & ) → 모든 속성을 가진 결합 타입
  • 유니온 + 태그 조합 → 실무 최강 패턴