(Distributive Conditional Types)
type StringNumberSwitch<T> = T extends number ? string : number;
let varA: StringNumberSwitch<number>; // string
let varB: StringNumberSwitch<string>; // number
let varC: StringNumberSwitch<number | string>; // number | string 유니온타입
// 1. let varC: StringNumberSwitch<number>; → string
// 2. let varC: StringNumberSwitch<string>; → number
type Exclude<T, U> = T extends U ? never : T;
type A = Exclude<number | string | boolean, string>; // number | boolean 유니온 타입
// type A = Exclude<number , string>; → number
// type A = Exclude<string , string>; → never
// type A = Exclude<boolean , string>; → boolean
// 결과: number | never | boolean 합집합 → number | boolean 유니온 타입
type Extract<T, U> = T extends U ? T : never;
type B = Extract<number | string | boolean, string>; // string 타입
// type A = Exclude<number , string>; → never
// type A = Exclude<string , string>; → string
// type A = Exclude<boolean , string>; → never
// 결과: never | string | never 합집합 → string 타입