본문 바로가기
language/typescript

🔀 유니언 타입 vs 인터섹션 타입 – | 와 &의 차이점 완벽 정리

by 죄니안죄니 2025. 4. 27.
📚 타입스크립트 입문 시리즈
🟢 ① tsconfig.json 완전 정복 | 🟢 ② 개발 환경 세팅 | 🟢 ③ 기본 타입 정복 | 🟢 ④ interface vs type | 🟢 ⑤ 함수 타입 선언 | 🔵 ⑥ 유니언 & 인터섹션 타입

🔀 유니언 타입 vs 인터섹션 타입 – | 와 &의 차이점 완벽 정리

타입스크립트에서는 두 개 이상의 타입을 결합하거나 조합해서 사용할 수 있는 기능이 있습니다.
바로 유니언(|)인터섹션(&) 타입입니다. 비슷해 보여도 의미는 완전히 다릅니다!


1️⃣ 유니언 타입 (Union Type)

유니언 타입은 '이거나 저거거나'를 의미합니다.

let status: 'success' | 'error' | 'loading';

status = 'success';   // ✅
status = 'error';     // ✅
status = 'idle';      // ❌ error

실무에서 API 응답 상태, 사용자 권한 등의 상황에 자주 사용됩니다.

📌 변수 타입 유니언

let id: number | string;

id = 123;      // ✅
id = 'abc123'; // ✅
id = true;     // ❌

📌 매개변수 유니언

function printId(id: number | string) {
  console.log('ID:', id);
}

유의사항: 유니언 타입 내 공통된 속성/메서드만 접근 가능

function getLength(input: string | number) {
  return input.length; // ❌ string에는 있지만 number에는 없음
}

✔ 타입 좁히기 (Type Narrowing)

function getLength(input: string | number) {
  if (typeof input === 'string') {
    return input.length;  // ✅ OK
  }
  return input.toString().length;
}

2️⃣ 인터섹션 타입 (Intersection Type)

인터섹션은 '이것도 저것도 모두 만족'하는 타입입니다.

type Name = { name: string };
type Age = { age: number };

type Person = Name & Age;

const user: Person = {
  name: '홍길동',
  age: 30,
};

📌 interface로 확장한 것과 동일

interface Name {
  name: string;
}
interface Age {
  age: number;
}
type Person = Name & Age;

이렇게 여러 개의 타입을 조합해서 하나의 객체 구조로 묶는 데 매우 유용합니다.


3️⃣ 비교 정리

항목 유니언 ( | ) 인터섹션 ( & )
의미 둘 중 하나만 만족 둘 다 모두 만족
예시 string | number { name } & { age }
사용 상황 매개변수 다형성, 상태 구분 객체 구조 조합
주의점 공통된 속성만 접근 가능 모든 속성 필수

🧠 실무 팁

  • Union상태 분기, Intersection객체 병합에 적합
  • React Props 같은 경우 공통 속성 + 옵션 조합 시 인터섹션을 자주 사용
  • 유니언을 쓸 땐 타입 좁히기(type narrowing)로 정확한 분기 처리 필수

✅ . React 컴포넌트에서 인터섹션(&) 타입 조합 예시

💡 공통 속성 + 옵션 속성 분리 패턴

type CommonProps = {
  id: string;
  label: string;
};

type TextInputProps = {
  type: 'text';
  maxLength?: number;
};

type CheckboxProps = {
  type: 'checkbox';
  checked: boolean;
};

// 인터섹션 타입 조합으로 실제 Prop 구성
type InputProps = CommonProps & (TextInputProps | CheckboxProps);

 

✅ 컴포넌트 예시

const CustomInput = (props: InputProps) => {
  const { id, label, ...rest } = props;

  return (
    <label htmlFor={id}>
      {label}
      {rest.type === 'text' ? (
        <input id={id} type="text" maxLength={rest.maxLength} />
      ) : (
        <input id={id} type="checkbox" checked={rest.checked} />
      )}
    </label>
  );
};

📌 이런 구조의 장점

  • id, label 같은 공통 속성은 CommonProps로 분리
  • text와 checkbox에 따른 속성 차이는 타입 분기로 표현
  • 유지보수, 가독성, 확장성 모두 향상

📘 다음 글 예고

👉 타입 추론과 단언 (as, !, ??, ??=) – TS가 타입을 어떻게 추론하고 제어하는지 알아봅니다.

 

댓글