Conditional Types ๐คฉ
ํ์
์คํฌ๋ฆฝํธ์์ ์กฐ๊ฑด๋ถ ํ์
์ T extends U ? X : Y์ ๊ฐ์ ํํ๋ก ์ฌ์ฉ๋๋ค. ์ด๋ T๊ฐ U์ ํ ๋น ๊ฐ๋ฅํ์ง์ ๋ฐ๋ผ์ X์ Y์ค ํ๋์ ํ์
์ ์ ํํ๊ฒ ๋๋ค.
์ด๋ฌํ ๋ชจ์ต์ ๊ธฐ์กด javascript์ ์ผํญ์ฐ์ฐ์์ ์ ์ฌํ๊ฒ ๋๊ปด์ง๋ค. (condition ? trueExpression : falseExpression)
interface Animal {
  live(): void
}
interface Dog extends Animal {
  woof(): void
}
type Example1 = Dog extends Animal ? number : string // type Example1 = number
type Example2 = RegExp extends Animal ? number : string // type Example2 = stringGeneric๊ณผ ํจ๊ป ์ฌ์ฉํ๊ธฐ
Generic๊ณผ ํจ๊ป ์ฌ์ฉํ๋ฉด ๋ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์๋ค. ๋ค์ ์์ ๋ฅผ ๋ณด์.
// ์์ 1
type MessageOf<T> = T extends { message: unknown } ? T["message"] : never
interface Email {
  message: string
}
interface Dog {
  bark(): void
}
type EmailMessageContents = MessageOf<Email> // string
type DogMessageContents = MessageOf<Dog> // never
// ์์ 2
type Flatten<T> = T extends any[] ? T[number] : T
// Extracts out the element type.
type Str = Flatten<string[]> // type Str = string
// Leaves the type alone.
type Num = Flatten<number> // type Num = numberInfer์ ํจ๊ป ์ฌ์ฉํ๊ธฐ
infer๋ ํ์
์คํฌ๋ฆฝํธ์์ ํ์
์ ์ถ๋ก ํ๋ ํค์๋์ด๋ค. infer๋ฅผ ์ฌ์ฉํ๋ฉด ์กฐ๊ฑด๋ถ ํ์
์ ์ฌ์ฉํด ๋์ ์ผ๋ก ํ์
์ ์ถ๋ก ํ  ๋ ์ ์ฉํ๊ฒ ์ฌ์ฉํ  ์ ์๋ค.
// ์์1
type Flatten<Type> = Type extends Array<infer Item> ? Item : Type
//์์2
type GetReturnType<Type> = Type extends (...args: never[]) => infer Return
  ? Return
  : never
type Num = GetReturnType<() => number> // number
type Str = GetReturnType<(x: string) => string> // string
type Bools = GetReturnType<(a: boolean, b: boolean) => boolean[]> // boolean[]์์ 2๋ฅผ ๋ณด๋ฉด ํจ์์ ๋ฐํํ์ ์ ๋์ ์ผ๋ก ๋ณ๊ฒฝํ ์ ์๊ฒ infer๋ฅผ ์ด์ฉํด ์ถ๋ก ํ ์์ ๋ค.
Distributive Conditional Types
Distributive Conditional Types๋ ์กฐ๊ฑด๋ถ ํ์
์ด ์ฌ์ฉ๋  ๋ ์ ๋ฌ๋๋ ํ์
์ด union์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ผ๋ฉด ๊ฐ๊ฐ์ ํ์
์ ์กฐ๊ฑด๋ถ ํ์
์ ์ ์ฉํ ํ union์ผ๋ก ๋ค์ ํฉ์ณ์ง๋ค.
type ToArray<Type> = Type extends any ? Type[] : never
type StrArrOrNumArr = ToArray<string | number> // string[] | number[]