<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

타입 검사를 위한 컨디셔널 타입

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'

[주의] boolean 분배법칙은 true | false

type Union = string | boolean | number;
type Type<T> = T extends string | boolean ? T[] : never;

let n: Type<Union> = ['hi']; // let n: string[] | true[] | false[]