
교집합이 없는 타입들로만 만든 유니온 타입
string과number타입은 겹치는 부분이 없다. 이것을 보고 "서로소 관계에 있다" 라고 함
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)에 접근할 수 있다.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 처럼 잘게 쪼개어 state나 tag같은 프로퍼티를 추가해서 서로소 유니온타입을 만들어주는게 좋음switch-case문을 사용하여 TypeScript가 task의 타입을 자동으로 좁혀주어 같은 타입 단언 없이도 직관적이고 안정적이게 필요한 프로퍼티(response, error)에 접근할 수 있다.타입을 LOADING | SUCCESS | FAILED처럼 상태별로 쪼개고, state 같은 판별자(discriminator) 를 리터럴 타입으로 두면 판별 가능한 유니온(서로소 유니온) 을 만들 수 있다.
이렇게 하면 switch (task.state) 분기 안에서 TypeScript가 task의 타입을 자동으로 좁혀주기 때문에, ! 같은 타입 단언 없이도 안전하게 필요한 프로퍼티(response, error)에 접근할 수 있다.
한 입 크기로 잘라먹는 타입스크립트
https://www.inflearn.com/course/한입-크기-타입스크립트/dashboard