← λͺ©λ‘μœΌλ‘œ
Infer

TypeScriptλ₯Ό μ‚¬μš©ν•˜λ‹€ 보면 λ”μš± μ •κ΅ν•œ νƒ€μž… μ‹œμŠ€ν…œμ˜ ν•„μš”μ„±μ„ 느끼게 λ©λ‹ˆλ‹€. 특히, λ³΅μž‘ν•œ μ œλ„€λ¦­ νƒ€μž…μ„ λ‹€λ£° λ•ŒλŠ” 쑰건뢀 νƒ€μž…(Conditional Types)κ³Ό ν•¨κ»˜ infer ν‚€μ›Œλ“œκ°€ 맀우 μœ μš©ν•˜κ²Œ μ‚¬μš©λ  수 μžˆμŠ΅λ‹ˆλ‹€.
TypeScript의 infer ν‚€μ›Œλ“œκ°€ 무엇인지, 그리고 μ–΄λ–»κ²Œ ν™œμš©ν•  수 μžˆλŠ”μ§€μ— λŒ€ν•΄ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

inferλž€ λ¬΄μ—‡μΈκ°€μš”?

inferλŠ” TypeScript의 쑰건뢀 νƒ€μž…μ—μ„œ μ‚¬μš©λ˜λŠ” ν‚€μ›Œλ“œλ‘œ, νŠΉμ • νƒ€μž…μ˜ 일뢀λ₯Ό μΆ”λ‘ ν•  수 μžˆλ„λ‘ λ„μ™€μ€λ‹ˆλ‹€. μ‰½κ²Œ 말해, inferλŠ” μ œλ„€λ¦­ νƒ€μž…μ„ λΆ„μ„ν•˜μ—¬ μƒˆλ‘œμš΄ νƒ€μž…μ„ μΆ”μΆœν•˜λŠ” 역할을 ν•©λ‹ˆλ‹€.

κΈ°λ³Έ μ‚¬μš© 예제

λ¨Όμ €, infer의 기본적인 μ‚¬μš©λ²•μ„ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€. μ—¬κΈ°μ„œλŠ” ν•¨μˆ˜μ˜ λ°˜ν™˜ νƒ€μž…μ„ μΆ”λ‘ ν•˜λŠ” 예제λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

type GetReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

μœ„ μ½”λ“œμ—μ„œ GetReturnType νƒ€μž…μ€ μ œλ„€λ¦­ Tκ°€ ν•¨μˆ˜ νƒ€μž…μΈ 경우, κ·Έ ν•¨μˆ˜μ˜ λ°˜ν™˜ νƒ€μž…μ„ μΆ”λ‘ ν•˜μ—¬ R둜 μ„€μ •ν•©λ‹ˆλ‹€. λ§Œμ•½ ν•¨μˆ˜ νƒ€μž…μ΄ μ•„λ‹ˆλΌλ©΄ neverλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
이 νƒ€μž…μ„ μ‚¬μš©ν•˜λ©΄ νŠΉμ • ν•¨μˆ˜μ˜ λ°˜ν™˜ νƒ€μž…μ„ μžλ™μœΌλ‘œ μΆ”λ‘ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ‹€μ „ ν™œμš© 예제

이제 infer ν‚€μ›Œλ“œλ₯Ό μ‹€μ „μ—μ„œ μ–΄λ–»κ²Œ ν™œμš©ν•  수 μžˆλŠ”μ§€ λͺ‡ κ°€μ§€ 예제λ₯Ό 톡해 μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

  1. ν•¨μˆ˜ 인수 νƒ€μž… μΆ”μΆœ

inferλ₯Ό μ‚¬μš©ν•˜λ©΄ ν•¨μˆ˜μ˜ 인수 νƒ€μž…μ„ μΆ”μΆœν•  수 μžˆμŠ΅λ‹ˆλ‹€.

type GetArguments<T> = T extends (...args: infer A) => any ? A : never;

type Args1 = GetArguments<(x: number, y: string) => void>; // [number, string]
type Args2 = GetArguments<() => void>; // []

이 μ½”λ“œμ—μ„œ GetArguments νƒ€μž…μ€ μ£Όμ–΄μ§„ ν•¨μˆ˜μ˜ 인수 νƒ€μž…μ„ λ°°μ—΄λ‘œ λ°˜ν™˜ν•©λ‹ˆλ‹€. 이λ₯Ό 톡해 ν•¨μˆ˜μ˜ 인수 νƒ€μž…μ„ μ‰½κ²Œ μΆ”μΆœν•  수 μžˆμŠ΅λ‹ˆλ‹€.

  1. ν”„λ‘œλ―ΈμŠ€μ˜ λ°˜ν™˜ νƒ€μž… μΆ”μΆœ

inferλŠ” ν”„λ‘œλ―ΈμŠ€ νƒ€μž…μ˜ λ°˜ν™˜ 값을 μΆ”λ‘ ν•˜λŠ” 데도 맀우 μœ μš©ν•©λ‹ˆλ‹€.

type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;

type Example1 = UnwrapPromise<Promise<string>>; // string
type Example2 = UnwrapPromise<number>; // number

UnwrapPromise νƒ€μž…μ€ ν”„λ‘œλ―ΈμŠ€μ—μ„œ λ°˜ν™˜λ˜λŠ” μ‹€μ œ νƒ€μž…μ„ μΆ”λ‘ ν•©λ‹ˆλ‹€. ν”„λ‘œλ―ΈμŠ€ νƒ€μž…μ΄ μ•„λ‹Œ κ²½μš°μ—λŠ” μ›λž˜ νƒ€μž…μ„ κ·ΈλŒ€λ‘œ λ°˜ν™˜ν•©λ‹ˆλ‹€.

  1. λ°°μ—΄ μš”μ†Œ νƒ€μž… μΆ”μΆœ

λ°°μ—΄ νƒ€μž…μ—μ„œ μš”μ†Œμ˜ νƒ€μž…μ„ μΆ”μΆœν•˜λŠ” 방법도 infer둜 κ°„λ‹¨ν•˜κ²Œ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

type ElementType<T> = T extends (infer U)[] ? U : T;

type Example1 = ElementType<string[]>; // string
type Example2 = ElementType<number[]>; // number

ElementType νƒ€μž…μ€ λ°°μ—΄μ˜ μš”μ†Œ νƒ€μž…μ„ λ°˜ν™˜ν•˜λ©°, 배열이 μ•„λ‹Œ νƒ€μž…μ΄ μ£Όμ–΄μ§ˆ 경우 κ·Έ νƒ€μž… 자체λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

  1. νŠœν”Œμ—μ„œ νŠΉμ • μœ„μΉ˜μ˜ νƒ€μž… μΆ”μΆœ

νŠœν”Œ νƒ€μž…μ—μ„œ 첫 번째 μš”μ†Œμ˜ νƒ€μž…μ„ μΆ”μΆœν•  λ•Œλ„ inferλ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

type First<T> = T extends [infer U, ...any[]] ? U : never;

type Example1 = First<[string, number, boolean]>; // string
type Example2 = First<[boolean, number]>; // boolean

First νƒ€μž…μ€ νŠœν”Œμ˜ 첫 번째 μš”μ†Œ νƒ€μž…μ„ μΆ”μΆœν•˜μ—¬ μœ μš©ν•˜κ²Œ ν™œμš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.