[TypeScript] 서로소 유니온 타입

kjy0124·2026년 2월 24일
post-thumbnail

🎯 서로소 유니온 타입

교집합이 없는 타입들로만 만든 유니온 타입
stringnumber 타입은 겹치는 부분이 없다. 이것을 보고 "서로소 관계에 있다" 라고 함

✅ switch-case문 활용

type Admin = {
  tag: "ADMIN";
  name: string;
  kickCount: number;
};

type Member = {
  tag: "MEMBER";
  name: string;
  point: number;
};

type Guest = {
  tag: "GUEST";
  name: string;
  visitCount: number;
};

// 서로소 유니온 타입
type User = Admin | Member | Guest;

function login(user: User) {
  switch (user.tag) {
    case "ADMIN": {
      console.log(
        `${user.name}님 현재까지 ${user.kickCount}명 강퇴하였습니다.`,
      );
      break;
    }
    case "MEMBER": {
      console.log(`${user.name}님 현재까지 ${user.point}모았습니다.`);
      break;
    }
    case "GUEST": {
      console.log(
        `${user.name}님 현재까지 ${user.visitCount}번 방문하였습니다.`,
      );
      break;
    }
  }
}
  • 위 코드의 User는 Admin | Member | Guest로 이루어진 유니온 타입이며, tag라는 판별자(discriminator) 를 통해 각 타입이 명확히 구분되는 서로소 유니온(Discriminated Union) 이다.
  • tag 값이 "ADMIN" | "MEMBER" | "GUEST"처럼 서로 겹치지 않는 리터럴이기 때문에, switch (user.tag)로 분기하면 각 case 안에서 user의 타입이 자동으로 좁혀져(Admin, Member, Guest) 안전하게 프로퍼티(kickCount, point, visitCount)에 접근할 수 있다.

✅ 사용 예시2

type LoadingTask = {
  state: "LOADING";
};
type SuccessTask = {
  state: "SUCCESS";
  response: {
    data: "data";
  };
};
type FailedTask = {
  state: "FAILED";
  error: {
    message: "ERROR";
  };
};

type AsyncTask = LoadingTask | SuccessTask | FailedTask;

function processResult(task: AsyncTask) {
  switch (task.state) {
    case "LOADING": {
      console.log("로딩중");
      break;
    }
    case "SUCCESS": {
      console.log(`성공 : ${task.response.data}`);
      break;
    }
    case "FAILED": {
      console.error(`오류 발생 : ${task.error.message}`);
      break;
    }
  }
}
  • 타입들을 LOADING | SUCESS | FAILED 처럼 잘게 쪼개어 statetag같은 프로퍼티를 추가해서 서로소 유니온타입을 만들어주는게 좋음
  • 그렇게 된다면 switch-case문을 사용하여 TypeScript가 task의 타입을 자동으로 좁혀주어 같은 타입 단언 없이도 직관적이고 안정적이게 필요한 프로퍼티(response, error)에 접근할 수 있다.

타입을 LOADING | SUCCESS | FAILED처럼 상태별로 쪼개고, state 같은 판별자(discriminator) 를 리터럴 타입으로 두면 판별 가능한 유니온(서로소 유니온) 을 만들 수 있다.

이렇게 하면 switch (task.state) 분기 안에서 TypeScript가 task의 타입을 자동으로 좁혀주기 때문에, ! 같은 타입 단언 없이도 안전하게 필요한 프로퍼티(response, error)에 접근할 수 있다.


출처

한 입 크기로 잘라먹는 타입스크립트
https://www.inflearn.com/course/한입-크기-타입스크립트/dashboard

profile
개발 공부...

0개의 댓글