= 태그된 유니온 Tagged Union
: 타입 좁히기에 널리 사용되는 방식
.
.
.
: 유효성 검사
유효성 에러 발생 -> 에러코드 & 에러메시지
이때, 에러 노출 방식데 따라 추가 필요정보 필요 가능
type TextError = {
errorCode: string;
errorMessage: string;
};
type ToastError = {
errorCode: string;
errorMessage: string;
toastshowDuration: number; // 토스트를 띄워줄 시간
};
type AlertError = {
errorCode: string;
errorMessage: string;
onConfirm: O=> Void; / 얼럿 창의 확인 버튼을 누른 뒤 액션
};
type ErrorFeedbackType = TextError | ToastError | AlertError;
const errorArr: ErrorFeedbackType[] = [
{ errorCode: "100", errorMessage: "텍스트 에러" },
{ errorcode: "200", erroressage: "토스트 에러", toastShowburation: 3000 },
{errorcode: "300", errortessage: "얼럿 에러", onConfirm: ()=> {} },
];
ErrorFeedbackType의 원소를 갖는 배열 errorArr를 정의 -> 다양한 에러 객체 관리 가능
const errorArr: ErrorFeedbackType[] = [
//...
{
errorCode: "999",
errorMessage: "잘못된 에러",
toastShowDuration: 3000,
onConfirm: () => {},
}, // expected error
];
-> 타입 에러가 발생하지 않는다면 무수한 에러 객체가 생겨날 위험성 높아짐.
type TextError = {
errorType: "TEXT";
errorCode: string;
errorMessage: string;
}
type ToastError = {
errorType: "TOAST";
errorCode: string;
errorMessage: string;
toastShowDuration: number;
}
type AlertError = {
errorType: "ALERT";
errorCode: string;
errorMessage: string;
onConfirm: () => void;
};
type ErrorFeedbackType = TextError | ToastError | AlertError;
const errorArr: ErrorFeedbackType[] = [
{errorType: TEXT errorCode: "100", errorMessage: "텍스트 에러" },
{
errorType: "TOAST",
errorCode: "200",
errorMessage: "토스트 에러",
toastShowDuration: 3000,
},
{
errorType: "ALERT",
errorCode: "300",
errorMessage: "얼럿 에러",
onConfirm: () => {},
},
{
errorType: "TEXT",
errorCode: "999",
errorMessage: "잘못된 에러",
toastShowDuration: 3000, // Object Literal may only specify known properties, and 'toastShowDuration' does not exist in type 'TextError'
onConfirm: () => {},
},
{
errorType: "TOAST",
errorCode: "210",
errorMessage: "토스트 에러",
onConfirm: () => {}, // Object Literal may only specify known properties, and 'onConfirm' does not exist in type 'ToastError'
},
{
errorType: "ALERT",
errorCode: "310",
errorMessage: "얼럿 에러",
toastShowDuration: 5000, // Object Literal may only specify known properties, and 'toastShowDuration' does not exist in type 'AlertError'
},
];
: 정확하지 않은 여러 객체에 대해 타입 에러가 발생하는 것 확인 가능.
식별할 수 있는 유니온을 사용할 때 주의점 )
: 식별할 수 있는 유니온의 판별자는 유닛타입 unit type으로 사용되어야 정상 작동함.
유닛 타입 unit type
: 다른 타입으로 쪼개지지 않고 오직 하나의 정확한 값을 가지는 타입
null, undefined, 리터럴 타입을 비롯해 true, 1
<-> 다양한 타입 할당 : void, string, number
interface A {
value: "a"; // unit type
answer: 1;
}
interface B {
value: string; // not unit type
answer: 2;
}
interface C {
value: Error; // instantiable type
answer: 3;
}
type Unions = A | B | C;
function handle(param: Unions) {
/**판별자가 value일 때 */
param.answer; // 1 | 2 | 3
// a 가 리터럴 타입이므로 타입이 좁혀진다.
// 단, 이는 String 타입에 포함되므로 param은 A 또는 B 타입으로 좁혀진다
if (param.value === "a") { param.answer; // 1 | 2 return;
}
// 유닛 타입이 아니거나 인스턴스화할 수 있는 타입일 경우 타입이 좁혀지지 않는다
if (typeof param.value === "string") {
param.answer; // 1 | 2 | 3 return;
}
if (param.value instanceof Error) {
param.answer; // 1 | 2 | 3 return;
}
/**: 판별자가 answer일 때 */
param.value; // string | Error
// 판별자가 유닛 타입이므로 타입이 좁혀진다
if (param.answer === 1) {
param.value; // 'a'
}
}
판별자 = value
: 판별자로 선정한 값 중 'a'만 유일하게 유닛 타입.
이때만 유닛 타입 포함해서 -> 타입이 좁혀짐.
판별자 = answer
: 판별자가 모두 유닛 타입 -> 타입이 정상적으로 좁혀짐.
도서참조 : 우아한 타입스크립트 with 리액트