![[TypeScript] μ‘°κ±΄λΆ νμ](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FleG6X%2FbtsEWA3l8I9%2FD1aksYQb6mUGVxEW1Bnrv1%2Fimg.png)
π μ‘°κ±΄λΆ νμ μ΄λ 무μμΈκ°μ?
TypeScriptμ μ‘°κ±΄λΆ νμ (Conditional Types)μ νμ μμ€ν λ΄μμ 쑰건문μ μ¬μ©ν μ μκ² ν΄μ£Όλ κΈ°λ₯μ΄μμ. μ΄λ₯Ό ν΅ν΄ μ λ ₯λ νμ μ λ°λΌ λ€λ₯Έ νμ μ λ°νν μ μμΌλ©°, μ΄λ TypeScriptμ νμ μμ€ν μ λμ± μ μ°νκ³ λμ μΌλ‘ λ§λ€μ΄ μ€μ.
μ‘°κ±΄λΆ νμ
μ TypeScriptμμ T extends U ? X : Y
μ κ°μ ννλ‘ ννλΌμ. μ¬κΈ°μ T
κ° U
νμ
μ ν λΉ κ°λ₯νμ§ μ¬λΆμ λ°λΌ X
νμ
μ λ°ννκ±°λ, κ·Έλ μ§ μμΌλ©΄ Y
νμ
μ λ°νν΄μ. μ΄λ νλ‘κ·Έλλ°μμμ μΌλ°μ μΈ μ‘°κ±΄λ¬Έ(if-else)κ³Ό μ μ¬ν κ°λ
μ΄μμ.
μ‘°κ±΄λΆ νμ
μ 'λλ‘μ λΆκΈ°μ 'μ λΉμ ν μ μμ΄μ. μ¬λ¬λΆμ΄ μ΄μ μ νλ€κ° λλ‘κ° λ κ°λλ‘ λλλ μ§μ μ λλ¬νλ€κ³ μμν΄ λ³΄μΈμ. μ΄λ, μ¬λ¬λΆμ λͺ©μ μ§μ λ°λΌ μΌμͺ½ λλ μ€λ₯Έμͺ½ κΈΈμ μ νν΄μΌ ν΄μ. μ‘°κ±΄λΆ νμ
μμλ μ΄λ¬ν 'λΆκΈ°μ 'μ΄ νμ
μ΄ νΉμ 쑰건(T extends U
)μ λ§μ‘±νλμ§ μ¬λΆμ λ°λΌ κ²°μ λΌμ. 쑰건μ λ§μ‘±νλ©΄ 'μΌμͺ½ κΈΈ'(νμ
X
)μ μ ννκ³ , κ·Έλ μ§ μμΌλ©΄ 'μ€λ₯Έμͺ½ κΈΈ'(νμ
Y
)μ μ ννλ κ²κ³Ό κ°μμ.
π₯οΈ μ‘°κ±΄λΆ νμ μ ꡬ쑰μ μ¬μ© μμ
1. μ‘°κ±΄λΆ νμ μ ꡬ쑰
- νμ
μ€ν¬λ¦½νΈμ μ‘°κ±΄λΆ νμ
μ λ€μκ³Ό κ°μ κΈ°λ³Έ ννλ₯Ό κ°μ§κ³ μμ΄μ:
- μ΄ κ΅¬μ‘°λ νλ‘κ·Έλλ°μμ μΌλ°μ μΌλ‘ μ¬μ©λλ 쑰건문(if-else)κ³Ό μ μ¬ν΄μ. μ‘°κ±΄λΆ νμ μ νμ μμ€ν λ΄μμ "λ§μ½ TypeAκ° TypeBμ ν λΉ κ°λ₯νλ€λ©΄ TypeCλ₯Ό μ¬μ©νκ³ , κ·Έλ μ§ μλ€λ©΄ TypeDλ₯Ό μ¬μ©νλ€"λ λ‘μ§μ ꡬνν΄μ.
TypeA extends TypeB ? TypeC : TypeD;
'TypeA extends TypeB'λ 쑰건 ννμμ λλ€.
μ΄ ννμμ 'TypeA'κ° 'TypeB'μ μλΈ νμ μ΄κ±°λ, λ€μ λ§ν΄ 'TypeA'κ° 'TypeB'μ ν λΉ κ°λ₯νμ§λ₯Ό νκ°ν©λλ€.
'?' λ°λ‘ λ€μ μ€λ 'TypeC'λ μ‘°κ±΄μ΄ μ°ΈμΌ λ μ¬μ©λλ νμ μ λλ€.
':' λ°λ‘ λ€μ μ€λ 'TypeD'λ μ‘°κ±΄μ΄ κ±°μ§μΌ λ μ¬μ©λλ νμ μ λλ€.
2. μ‘°κ±΄λΆ νμ μ μ¬μ© μμ
μ‘°κ±΄λΆ νμ μ νμ μ 쑰건μ λ°λΌ λ€λ₯Έ νμ μ λ°νν μ μκ² ν΄ μ£Όμ΄, νμ μ€ν¬λ¦½νΈμ νμ μμ€ν μ λμ± μ μ°νκ² λ§λ€μ΄μ.
type IsNumber<T> = T extends number ? "Yes" : "No";
'IsNumber'λ μ λ€λ¦ νμ Tκ° number νμ μ ν λΉ κ°λ₯νμ§ μ¬λΆμ λ°λΌ "Yes" λλ "No"λ₯Ό λ°ννλ μ‘°κ±΄λΆ νμ μ λλ€.
'T extends number'λ Tκ° number νμ μ ν λΉ κ°λ₯νμ§ κ²μ¬ν©λλ€. μ΄λ Tκ° number νμ μ΄κ±°λ number νμ μΌλ‘ λ³νλ μ μλμ§λ₯Ό μλ―Έν©λλ€.
'? "Yes" : "No"'λ μ‘°κ±΄μ΄ μ°Έμ΄λ©΄ "Yes"λ₯Ό, κ±°μ§μ΄λ©΄ "No"λ₯Ό λ°νν©λλ€.
type Result1 = IsNumber<42>;
μμ42
λnumber
νμ μ΄λ―λ‘,IsNumber<42>
λ"Yes"
λ₯Ό κ²°κ³Όλ‘ ν΄μ.
type Result1 = IsNumber<42>; // "Yes"
'IsNumber<42>', μ¬κΈ°μ 'T'λ 리ν°λ΄ νμ 42μ λλ€.
42λ 'number' νμ μ ν λΉ κ°λ₯νλ―λ‘, μ‘°κ±΄λΆ νμ μ '"Yes"'λ₯Ό λ°νν©λλ€.
type Result2 = IsNumber<"Hello">;
μμ"Hello"
λstring
νμ μ΄κΈ° λλ¬Έμnumber
νμ μ ν λΉ κ°λ₯νμ§ μμμ. λ°λΌμ,IsNumber<"Hello">
λ"No"
λ₯Ό κ²°κ³Όλ‘ ν΄μ.
type Result2 = IsNumber<"Hello">; // "No"
'IsNumber<"Hello">', μ΄ κ²½μ° 'T'λ λ¬Έμμ΄ λ¦¬ν°λ΄ νμ "Hello"μ λλ€.
"Hello"λ 'number' νμ μ ν λΉν μ μμΌλ―λ‘, μ‘°κ±΄λΆ νμ μ '"No"'λ₯Ό λ°νν©λλ€.
π€ μ‘°κ±΄λΆ νμ μ κ³ κΈ μ¬μ©λ²
μ‘°κ±΄λΆ νμ μ λ 볡μ‘ν νμ μ°μ°κ³Ό ν¨κ» μ¬μ©λ μ μμ΄μ. μλ₯Ό λ€μ΄, λ νμ μ€ νλλ₯Ό μ ννλ μ νΈλ¦¬ν° νμ μ λ§λ€κ±°λ, νμ μ λ°λΌ λ€λ₯Έ νμ μ λ°ννλ 맀ν νμ μ μμ±νλ λ° μ¬μ©ν μ μμ΄μ.
1. νμ νν°λ§
- νμ νν°λ§μ μ£Όμ΄μ§ μ λμ¨ νμ μμ νΉμ 쑰건μ λ§μ‘±νλ νμ λ§ μΆμΆνλ ν¨ν΄μ΄μμ.
type FilterNumber<T> = T extends number ? T : never;
type Result = FilterNumber<string | number | boolean>; // number
'FilterNumber'λ μ λμ¨ νμ 'T'μμ 'number' νμ λ§μ μΆμΆν©λλ€.
'extends' ν€μλλ₯Ό μ¬μ©νμ¬ κ° μ λμ¨ νμ μ λ©€λ²κ° 'number'μ ν λΉ κ°λ₯νμ§ νμΈνκ³ , ν λΉ κ°λ₯ν κ²½μ° κ·Έ νμ μ κ·Έλλ‘ μ¬μ©νλ©°, κ·Έλ μ§ μμ κ²½μ° 'never' νμ μ λ°νν©λλ€.
λ°λΌμ, 'Result' νμ μ 'number'κ° λ©λλ€.
2. νμ
μΆλ‘ κ³Ό infer
ν€μλ
infer
ν€μλλ μ‘°κ±΄λΆ νμ λ΄μμ νμ μ λμ μΌλ‘ μΆλ‘ νλ λ° μ¬μ©λΌμ. μ΄λ μ£Όλ‘ μ λ€λ¦ νμ μ νΉμ λΆλΆμ "μΆμΆ"ν λ μ μ©ν΄μ.
type ElementType<T> = T extends (infer U)[] ? U : never;
type T1 = ElementType<number[]>; // number
type T2 = ElementType<string[]>; // string
'ElementType'λ λ°°μ΄ 'T'μ μμ νμ μ μΆλ‘ ν©λλ€.
'T'κ° μ΄λ€ νμ μ λ°°μ΄μ΄λΌλ©΄, ν΄λΉ νμ μ 'U'λ‘ μΆλ‘ νκ³ , κ·Έ νμ μ λ°νν©λλ€.
λ§μ½ 'T'κ° λ°°μ΄μ΄ μλλΌλ©΄, 'never'λ₯Ό λ°νν©λλ€. λ°λΌμ, 'T1'μ 'number', 'T2'λ 'string'μ΄ λ©λλ€.
3. μ‘°κ±΄λΆ νμ μ μ΄μ©ν νμ 맀ν
- μ‘°κ±΄λΆ νμ μ κ°μ²΄ λ΄μ κ° μμ± νμ μ λ³ννλ λ°μλ μ¬μ©ν μ μμ΄μ. μ΄λ 맀νλ νμ κ³Ό ν¨κ» μ¬μ©λμ΄, κ°μ²΄μ κ° μμ±μ λν΄ νΉμ μ°μ°μ μνν μ μκ² ν΄μ.
type ReadonlyProperties<T> = {
[P in keyof T]: T[P] extends Function ? T[P] : Readonly<T[P]>;
};
interface Person {
name: string;
age: number;
greet(): void;
}
type ReadonlyPerson = ReadonlyProperties<Person>;
'ReadonlyProperties'λ κ°μ²΄ 'T'μ κ° μμ±μ κ²μ¬νμ¬, μμ± νμ μ΄ 'Function'μΈ κ²½μ° κ·Έλλ‘ λκ³ , κ·Έλ μ§ μμ κ²½μ°μλ 'Readonly' νμ μΌλ‘ λ³νν©λλ€.
μ΄λ₯Ό ν΅ν΄ 'Person' μΈν°νμ΄μ€μ 'name'κ³Ό 'age' μμ±μ μ½κΈ° μ μ©μ΄ λμ§λ§, 'greet' λ©μλλ λ³κ²½λμ§ μμ΅λλ€.
π¨ μ£Όμν μ
μ‘°κ±΄λΆ νμ μ μ¬μ©ν λλ λͺ κ°μ§ μ£Όμν΄μΌ ν μ μ΄ μμ΄μ. μ΄λ¬ν μ£Όμ μ¬νμ μ΄ν΄νκ³ μ μ ν λμ²ν¨μΌλ‘μ¨, μ½λμ κ°λ μ±μ λμ΄κ³ , μμμΉ λͺ»ν λ²κ·Έλ₯Ό λ°©μ§ν μ μμ΄μ.
- 볡μ‘μ± κ΄λ¦¬
- μ£Όμ μ¬ν: μ‘°κ±΄λΆ νμ μ λ§€μ° κ°λ ₯νμ§λ§, μ¬μ©μ΄ κ³Όλνκ±°λ 볡μ‘ν΄μ§λ©΄ μ½λμ κ°λ μ±κ³Ό μ μ§ κ΄λ¦¬κ° μ΄λ €μμ§ μ μμ΄μ.
- λμ² λ°©μ: κ°λ₯ν ν κ°κ²°νκ² μ μ§νκ³ , 볡μ‘ν μ‘°κ±΄λΆ νμ μ μμ λ¨μλ‘ λΆλ¦¬νμ¬ κ΄λ¦¬νλ κ²μ΄ μ’μμ.
- μν μ°Έμ‘°
- μ£Όμ μ¬ν: μ‘°κ±΄λΆ νμ μ μ¬μ©νμ¬ μλ‘ μ°Έμ‘°νλ νμ μ μ μν λ μν μ°Έμ‘°κ° λ°μν μ μμ΄μ. νμ μ€ν¬λ¦½νΈλ μν μ°Έμ‘°λ₯Ό μ²λ¦¬ν μ μμ§λ§, μ΄λ‘ μΈν΄ μ»΄νμΌλ¬μ μ±λ₯μ΄ μ νλκ±°λ μμμΉ λͺ»ν λμμ΄ λ°μν μ μμ΄μ.
- λμ² λ°©μ: μν μ°Έμ‘°κ° νμν κ²½μ°μλ μ£Όμ κΉκ² μ€κ³νκ³ , νμ μ μ μλ₯Ό κ°λ₯ν ν λ¨μνκ² μ μ§ν΄μΌ ν΄μ.
- νμ
μΆλ‘ κ³Ό
infer
μ¬μ©- μ£Όμ μ¬ν:
infer
ν€μλλ₯Ό μ¬μ©ν λλ νμ μ΄ μ¬λ°λ₯΄κ² μΆλ‘ λλμ§ μ£Όμ κΉκ² νμΈν΄μΌ ν΄μ. μλͺ»λ μΆλ‘ μ νμ μλ¬λ₯Ό λ°μμν€κ±°λ μμμΉ λͺ»ν κ²°κ³Όλ₯Ό μ΄λν μ μμ΄μ. - λμ² λ°©μ:
infer
μ¬μ© μ, νμ μΆλ‘ μ΄ μλν λλ‘ μλνλμ§ ν μ€νΈνκ³ , νμν κ²½μ° νμ μΆλ‘ μ λͺ μμ μΌλ‘ μ ννμ¬ μμ μ±μ λμ¬μΌ ν΄μ.
- μ£Όμ μ¬ν:
- μ λμ¨ νμ
κ³Όμ μνΈμμ©
- μ£Όμ μ¬ν: μ‘°κ±΄λΆ νμ μ μ λμ¨ νμ κ³Ό ν¨κ» μ¬μ©ν λ, κ° μ λμ¨ λ©€λ²μ λν΄ μ‘°κ±΄λΆ νμ μ΄ λ³λλ‘ μ μ©λΌμ. μ΄λ λλλ‘ μμμΉ λͺ»ν κ²°κ³Όλ₯Ό μ΄λν μ μμ΄μ.
- λμ² λ°©μ: μ λμ¨ νμ κ³Ό ν¨κ» μ‘°κ±΄λΆ νμ μ μ¬μ©ν λλ κ²°κ³Όλ₯Ό μ£Όμ κΉκ² κ²ν νκ³ , νμν κ²½μ° μ λμ¨ νμ μ λ¨Όμ μ μ (refinement)νκ±°λ λΆν΄(destructuring)νμ¬ μ²λ¦¬ν΄μΌ ν΄μ.
- μ±λ₯ κ³ λ €
- μ£Όμ μ¬ν: λ§€μ° λ³΅μ‘ν μ‘°κ±΄λΆ νμ μ νμ μ€ν¬λ¦½νΈ μ»΄νμΌλ¬μ μ±λ₯μ μν₯μ μ€ μ μμ΄μ.
- λμ² λ°©μ: μ±λ₯ λ¬Έμ κ° μμ¬λλ κ²½μ°, μ‘°κ±΄λΆ νμ μ 볡μ‘μ±μ μ€μ΄κ±°λ λ€λ₯Έ λ°©λ²μΌλ‘ λ¬Έμ λ₯Ό ν΄κ²°νλ κ²μ κ³ λ €ν΄μΌ ν΄μ.
π κ²°λ‘
μ‘°κ±΄λΆ νμ μ νμ μ€ν¬λ¦½νΈμμ 볡μ‘ν νμ λ‘μ§μ ꡬνν μ μκ² ν΄μ£Όλ κ°λ ₯ν λꡬμμ. μ΄ κΈ°λ₯μ μ¬μ©ν¨μΌλ‘μ¨, κ°λ°μλ 쑰건μ λ°λΌ νμ μ λΆκΈ°ν μ μμΌλ©°, μ΄λ λΌμ΄λΈλ¬λ¦¬ μμ±, API μλ΅ νμ μ²λ¦¬, μ νΈλ¦¬ν° νμ μμ± λ± λ€μν μν©μμ μ μ©νκ² νμ©λ μ μμ΄μ.
μ‘°κ±΄λΆ νμ μ ν¨κ³Όμ μΌλ‘ μ¬μ©νκΈ° μν΄μλ νμ μ€ν¬λ¦½νΈμ νμ μμ€ν μ λν κΉμ μ΄ν΄κ° νμν΄μ. λν, μ‘°κ±΄λΆ νμ μ λ¨μ©νλ©΄ μ½λμ 볡μ‘μ±μ΄ μ¦κ°ν μ μμΌλ―λ‘, νμν κ²½μ°μ μ μ ν μ¬μ©νλ κ²μ΄ μ€μν΄μ.
κ²°λ‘ μ μΌλ‘, μ‘°κ±΄λΆ νμ μ νμ μ€ν¬λ¦½νΈλ₯Ό μ¬μ©νλ κ°λ°μλ€μκ² λ§€μ° μ μ©ν κΈ°λ₯μ΄μμ. μ΄λ₯Ό ν΅ν΄ λμ± κ°λ ₯νκ³ μ μ°ν νμ μμ€ν μ ꡬμΆν μ μμΌλ©°, νμ κ΄λ ¨ λ¬Έμ λ₯Ό ν΄κ²°νλ λ° ν° λμμ΄ λΌμ. μ‘°κ±΄λΆ νμ μ μ¬λ°λ₯Έ μ¬μ©μ νμ μ€ν¬λ¦½νΈ νλ‘μ νΈμ νμ μμ μ±κ³Ό μ½λμ μ μ§λ³΄μμ±μ ν¬κ² ν₯μν μ μμ΄μ.
κ°λ°μλ‘μ νμ μ€ν¬λ¦½νΈμ μ΄λ¬ν κ³ κΈ κΈ°λ₯μ μμ§νκ³ νμ©νλ κ²μ, νμ μμ μ±μ΄ μ€μν μ ν리μΌμ΄μ μ κ°λ°ν λ ν° μ΄μ μ μ 곡ν΄μ. μ‘°κ±΄λΆ νμ μ ν¬ν¨ν νμ μ€ν¬λ¦½νΈμ λ€μν κΈ°λ₯μ μ κ·Ήμ μΌλ‘ νꡬνκ³ νμ©ν¨μΌλ‘μ¨, λμ± κ²¬κ³ νκ³ μ μ§λ³΄μκ° μ©μ΄ν μ½λλ² μ΄μ€λ₯Ό ꡬμΆν΄ λκ° μ μμ κ²μ΄μμ.
π μΆκ° μ 보
- νμ μ€ν¬λ¦½νΈμ μ‘°κ±΄λΆ νμ μ λν λ κΉμ μ΄ν΄λ₯Ό μνμ λ€λ©΄, TypeScript 곡μ λ¬Έμμμ μμΈν μ 보λ₯Ό μ°Ύμλ³Ό μ μμ΄μ.
'Language > TypeScript' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[TypeScript] Never νμ (1) | 2024.10.06 |
---|---|
[TypeScript] μ΄κ±°ν(Enums) (2) | 2024.10.05 |
[TypeScript] νμ κ°λ(Type Guard) (0) | 2024.04.20 |
[TypeScript] Interfaceμ Typeμ μ°¨μ΄ (0) | 2023.12.21 |
ν¬μ€ν μ΄ μ’μλ€λ©΄ "μ’μμβ€οΈ" λλ "ꡬλ ππ»" ν΄μ£ΌμΈμ!