
type Admin = {
name: string;
kickCount: number;
};
type Member = {
name: string;
point: number;
};
type Guest = {
name: string;
visitCount: number;
};
type User = Admin | Member | Guest;
function login(user: User) {
if ("kickCount" in user) { // Admin
console.log(`${user.name}님 현재까지 ${user.kickCount}명 추방했습니다`);
} else if ("point" in user) { // Member
console.log(`${user.name}님 현재까지 ${user.point}모았습니다`);
} else { // Guest
console.log(`${user.name}님 현재까지 ${user.visitCount}번 오셨습니다`);
}
}
문제점
- if-else_if 만 봤을대 user가 어떤 타입인지 한번에 알기 어려워서 타입 별칭 재확인 필요
- User는 유니온 타입으로 선언되었기 때문에 name 프로퍼티가 합성된다.
- name: string | string | string
해결방법: 리터럴 타입의 프로퍼티를 추가해서
서로소 유니온 타입을 만들어낸다.각 type에 tag 라는 프로퍼티를 추가하고 리터럴 타입으로 지정한다.
이 타입들을 Union 하게 되면 각 타입들은 서로소가 된다.
type Admin = {
tag: "ADMIN";
name: string;
kickCount: number;
};
type Member = {
tag: "MEMBER";
name: string;
point: number;
};
type Guest = {
tag: "GUEST";
name: string;
visitCount: number;
};
// if else_if
function login_if(user: User) {
if (user.tag === "ADMIN") {
console.log(`${user.name}님 현재까지 ${user.kickCount}명 추방했습니다`);
} else if (user.tag === "MEMBER") {
console.log(`${user.name}님 현재까지 ${user.point}모았습니다`);
} else {
console.log(`${user.name}님 현재까지 ${user.visitCount}번 오셨습니다`);
}
}
// case
function login_case(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;
}
}
}