: extends와 삼항연산자를 이용해서 조건에 따라 타입을 결정하는 문법
type A = number extends string ? string : number;
type ObjA = { // 슈퍼타입
a: number;
};
type ObjB = { // 서브타입
a: number;
b: number;
};
type B = ObjB extends ObjA ? number : string // 진실 => type B => number type
- 제네릭 조건부 타입
type StringNumberSwitch<T> = T extends number ? string : number;
let varA: StringNumberSwitch<number>; // 진실 => string
let varB: StringNumberSwitch<string>; // 거짓 => number
function removeSpaces<T>(text: T): T extends string ? string : undefined; // 오버로드 시그니쳐
function removeSpaces(text: any) {
if (typeof text === "string") {
// replaceAll 메서드 : 모든공백문자 " "(첫번째 인수)를 빈문자열 ""로 바꿔라
return text.replaceAll(" ", ""); // string 타입 값만 받음
} else {
return undefined;
}
}
let result = removeSpaces("hi im winterlood"); // hiimwinterlood
result.toUpperCase();
let result2 = removeSpaces(undefined); // undefined
함수 remobeSpaces 조건부 타입의 결과를 함수내부에서는 알수 없음 => 함수 오버로딩 이용
- 분산적인 조건부 타입
: 유니온 타입과 함께 조건부 타입을 사용할때 분산적으로 동작되게 하는 문법
type StringNumberSwitch<T> = T extends number ? string : number;
let c: StringNumberSwitch<number | string>; // string | number 유니언 타입
// StringNumberSwitch<number> | => string type
// StringNumberSwitch<string> => number type 으로 각각 분리됨
let d: StringNumberSwitch<boolean | number | string>; // string | number 유니언 타입
/* T를 내보냄 */
type Exclude<T, U> = T extends U ? never : T;
type A = Exclude<number | string | boolean, string>; // number | boolean 유니언 타입
// Exclude<number, string> | => T(거짓) -> number
// Exclude<string, string> | => never(참)
// Exclude<boolean, string> => T(거짓) -> boolean
// => number | never | boolean -> 유니언 타입에 never 타입(공집합) 은 삭제 됨
/* U를 내보냄 */
type Extract<T, U> = T extends U ? T : never;
type B = Extract<number | string | boolean, string>; // string type
// Extract<number, string> | => never(거짓)
// Extract<string, string> | => T(참) -> string
// Extract<boolean, string> => never(거짓)
// => never | string | never -> 유니언 타입에 never 타입(공집합) 은 삭제 됨
type StringNumberSwitch<T> = [T] extends [number] ? string : number;
let d: StringNumberSwitch<boolean | number | string>; // number type
** 조건부 타입 분산방지
- infer
: 조건부 타입내에서 특정 타입만 추론, R타입은 조건식을 참으로 만드는 타입을 추론
type FuncA = () => string;
type FuncB = () => number;
type ReturnType<T> = T extends () => infer R ? R : never;
type A = ReturnType<FuncA>; // (참) string type
type B = ReturnType<FuncB>; // (참) number type
// 추론 불가
type C = ReturnType<number>; // (거짓) never type
-> FuncA 와 () => infer R 비교, 참이 되려면 R -> string 타입, R타입 반환 -> type A는 string 타입이 됨
type PromiseUnpack<T> = T extends Promise<infer R> ? R : never;
type PromiseA = PromiseUnpack<Promise<number>>; // number
type PromiseB = PromiseUnpack<Promise<string>>; // string
// Promise<number> 와 Promise<infer R> 비교 => (참)R -> number
'Front > typescript' 카테고리의 다른 글
유틸리티 타입 (Utility Types) (0) | 2023.09.04 |
---|---|
타입 조작 (0) | 2023.08.25 |
제네릭 (0) | 2023.08.23 |
클래스 Classes (0) | 2023.08.23 |
인터페이스 (0) | 2023.08.23 |