개발/🔵 React-TypeScript
🔵 [React/TypeScript] 타입 좁히기, 서로소 유니온 타입
비니_
2025. 4. 5. 10:59
728x90
타입 좁히기
// 타입 좁히기
// 조건문 등을 이용해 넓은ㅇ 타입에서 좁은 타입으로 타입을 상황에 따라 좁히는 방법
type Person = {
name: string,
age: number
};
function func(value: number | string | Date | null | Person){
if(typeof value === 'number'){
console.log(value.toFixed());
}else if(typeof value === 'string'){
console.log(value.toUpperCase());
}
// else if(typeof value === 'object'){
// console.log(value.getTime());
// }
else if(value instanceof Date){
console.log(value.getTime());
}else if(value && "age" in value){
console.log(`${value.name}은 ${value.age}살 입니다.`);
}
}
서로소 유니온 타입 ** 개발자 스킬 업 될 수 있음 !! **
// 서로소 유니온 타입
// 교집합이 없는 타입들로만 만든 유니온 타입
type Admin = {
tag: "ADMIN";
name: string;
kickCount: number;
};
type Member = {
tag: "MEMBER";
name: string;
point: number;
kickCount: number;
};
type Guest = {
tag: "GUEST";
name: string;
visitCount: number;
};
type User = Admin | Member | Guest;
function login(user: User){
// 이런 식이면 겹치는 게 발생하기 때문에 하단처럼 tag를 써서 사용
// if("kickCount" in user){
// console.log(`${user.name}님 현재까지 ${user.kickCount}명 강퇴했습니다.`);
// }else if("point" in user){
// console.log(`${user.name}님 현재까지 ${user.point}포인트 모았습니다.`);
// }else{
// console.log(`${user.name}님 현재까지 ${user.visitCount}번 방문했습니다.ㄴ`);
// }
// 서로소 유니온 타입 / tag 사용
// 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}번 방문했습니다.ㄴ`);
// }
// 더 깔끔한 코드
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;
}
}
}
// 권장하지 않음
// type AsyncTask = {
// state: "LOADING" | "FAILED" | "SUCCESS";
// error?: {
// message: string;
// };
// response?: {
// data: string;
// };
// }
// 권장
type LoadingTask = {
state: "LOADING";
};
type FailedTask = {
state: "FAILED";
error: {
message: string;
}
};
type SuccessTask = {
state: "SUCCESS";
response: {
data: string;
}
};
type AsyncTask = LoadingTask | FailedTask | SuccessTask;
function processResult(task: AsyncTask){
switch(task.state){
case 'LOADING':{
console.log("로딩 중...");
break;
}
case 'FAILED':{
// console.log(`에러 발생: ${task.error!.message}`); // 권장하지 않음
console.log(`에러 발생: ${task.error.message}`);
// task // FailedTask라고 단언됨
break;
}
case 'SUCCESS':{
// console.log(`성공: ${task.response!.data}`); // 권장하지 않음
console.log(`성공: ${task.response.data}`);
break;
}
}
}
const loading: AsyncTask = {
state: "LOADING"
}
const failed: AsyncTask = {
state: "FAILED",
error: {
message: "오류발쉥"
}
}
const success: AsyncTask = {
state: "SUCCESS",
response: {
data: "데이터ㅓ어엉"
}
}
processResult(loading);728x90