<aside> 📌 조건에 따라 다른 타입이 되는 컨디셔널 타입
</aside>
interface Name {
name: string;
}
interface Person {
name: string;
age: number;
}
interface Animal extends Name {
age: number;
}
type A = Person extends Name ? string : number; // type A = string
type B = Animal extends Name ? string : number; // type B = string
extends
는 해당 타입에 대입할 수 있는지 없는지로 판단함
type HiString = 'hi' extends string ? true : false; // type HiString = true
type OneString = [1] extends [string] ? true : false; // type OneString = false
제네릭과 never 함께 사용하기
// 특정 타입이 아닌 경우 never 로 타입 지정하기
type GenericArr<T> = T extends string ? string[] : never;
type StrArr = GenericArr<string>; // type StrArr = string[]
type Never = GenericArr<number>; // type Never = never
type Test = GenericArr<'hi'>; // type Test = string[]
// 특정 타입의 속성 제거하기
type OmitByType<O, T> = {
[key in keyof O as O[key] extends T ? never : key]: O[key];
}
type NewType = OmitByType<{ // type NewType = { name: string; age: number; }
name: string;
age: number;
isMarried: boolean;
isStudent: boolean;
}, boolean>; // boolean 타입 속성 제거하기
<aside> 📌 검사하는 타입이 제네릭이면서 유니언이면 분배법칙이 실행된다!!
(A | B) extends U ? X : Y
(A extends U ? X : Y) | (B extends U ? X : Y)
</aside>
// CASE 1
type Animal = 'cat' | 'dog' | 'cow';
type Sound = Animal extends 'cat' ? 'meow' : 'moo'; // type Sound = 'moo'
// CASE 2
type Animal = 'cat' | 'dog' | 'cow';
type Sounds<T> = T extends 'cat' ? 'meow' : 'moo';
type Sound = Sounds<Animal>; // type Sound = 'meow' | 'moo'
CASE 1
CASE 2
'cat' extends 'cat' ? 'meow' : 'moo'; // 'meow'
'dog' extends 'cat' ? 'meow' : 'moo'; // 'moo'
'cow' extends 'cat' ? 'meow' : 'moo'; // 'moo'
type Union = string | boolean | number;
type Type<T> = T extends string | boolean ? T[] : never;
let n: Type<Union> = ['hi']; // let n: string[] | true[] | false[]