μ΄μ 1μ°¨ νμκ³Όμ μκ°μ΄ ν루λ°μ λ¨μ§ μμλ€...
λ°λΈμ½μ€μμ μ²μ λ§λ μ¬λλ€μ΄κΈ°λ νκ³ μ°μ¬κ³‘μ μ΄ λ§μ μ μ΄ λ€μλ νμ΄μλ νμ£ΌνμΈλ° λ²μ¨ ν€μ΄μ§ μκ°μ΄λΌλ.
μκ°μ΄ μμ² λΉ¨λ¦¬ μ§λκ°λ κ±° κ°λ€.
μ΄λ² μ£Όλ κ°μλ μ, νλ‘ νμ
μ€ν¬λ¦½νΈλ₯Ό λ§λ¬΄λ¦¬νκ³ λ€μμ£Ό μμμΌκΉμ§λ λ°©νμ΄λΌ μ¬μ λΉ μκ°μ΄λ€.
λ°©ν λμμλ νμ£Όνκ³Ό μ§ννλ €κ³ νλ λ―Έλκ²μμ²κ΅ μ¬μ΄λ νλ‘μ νΈλ₯Ό λ§λ¬΄λ¦¬νκ³ λΆμ‘±ν 곡λΆλ₯Ό λ ν κ²μ΄λ€.
νμ
μ€ν¬λ¦½νΈμμ ν¨μ μ€λ²λ‘λ©μ ν΅ν΄μ νμ
쑰건μ μΆκ°νλ€κ° 보면 μλ κ·Έλ¦Όκ³Ό κ°μ΄ μ½λκ° μμ² κΈΈμ΄μ§λ κ²½μ°κ° λ°μνλ€.
μ΄λ¬ν λΉν¨μ¨μ μΈ μ½λ μμ±μ ν΄κ²°νκΈ° μν΄μ μ¬μ©ν μ μλ κ°λ μ΄ μ λ€λ¦(Generic)μ΄λ€.
볡μ‘ν νμ μ‘°κ±΄μ΄ λ§€κ°λ³μμ λ°νκ°μ λμΌνκ² μ μ©λ κ²½μ° μ΄ νμ 쑰건μ λ³μννμ¬ μ μ©νλ κ²μ΄λ€.
μ λ€λ¦μ <>
κ΄νΈλ₯Ό ν΅ν΄ μ μΈ λ° νΈμΆν μ μλ€.
μ λ€λ¦μ μ΄λ¦μ μμ λ‘κ² μ€μ κ°λ₯νλ€.
function toObj<T>(a: T, b: T): { a: T; b: T } {
return { a, b }
}
toObj<string>('A', 'B')
toObj<number>(1, 2)
toObj<boolean>(true, false)
μ λ€λ¦μ νμ
μΆλ‘ μ μν΄ νΈμΆ μ μ λ€λ¦μ μλ΅νλλΌλ λ§€κ° λ³μκ° μ§μ λ κ²μΌλ‘ μΆλ‘ μ΄ κ°λ₯νλ©΄ μλ¬κ° λ°μνμ§ μλλ€.
λ°λλ‘ μΆλ‘ μ ν΅ν΄ μ¬λ°λ₯΄μ§ μμ νμ
μ΄ μ§μ λμμΌλ©΄ μλ¬κ° λ°μνλ€.
function toObj<T>(a: T, b: T): { a: T; b: T } {
return { a, b }
}
// 'A'λ₯Ό ν΅ν΄ aκ° string νμ
λ° Tκ° string νμ
μμ μ μ μμ΄
// μ λ€λ¦μ μλ΅ν΄λ μλ¬κ° λ°μνμ§ μλλ€.
toObj('A', 'B')
// 'A'λ₯Ό ν΅ν΄ μ λ€λ¦ Tκ° stringμΈλ° bμ νμ
μ΄ numberμ΄λ―λ‘
// μλ¬κ° λ°μνλ€.
toObj('A', 123) // 'number' νμμ μΈμλ 'string' νμμ λ§€κ° λ³μμ ν λΉλ μ μμ΅λλ€.
νμ§λ§ μμ toObj
μ ν¨μμ T
νμ
μλ null
μ΄λ undefined
νμ
μ΄ λ€μ΄κ°λ μλ¬κ° λ°μνμ§ μκ² λλ μΉλͺ
μ μΈ λ¬Έμ κ° μλ€.
λ°λΌμ μ λ€λ¦μ μ μ½μ‘°κ±΄κ³Ό ν¨κΌ μ¬μ©λμ΄μΌ μ΄λ¬ν λ¬Έμ λ₯Ό λ°©μ§ν μ μλ€. μ μ½μ‘°κ±΄μ extends
λ‘ μ€μ νλ€.
function toObj<T extends string | number | boolean>(
a: T,
b: T,
): { a: T; b: T } {
return { a, b }
}
μ μ½μ‘°κ±΄μ ν΅ν΄ T
νμ
μ 쑰건μ λͺ
μμ μΌλ‘ μ ν΄μ€μ μ¬μ©μκ° μνλ νμ
μ΄ μλ κ²μ μ¬μ©νμ§ μλλ‘ μ μ½μ κ±Έμ΄μΌ νλ€.
μ λ€λ¦μ ν¨μ λ§κ³ λ μΈν°νμ΄μ€, ν΄λμ€μλ μ¬μ© κ°λ₯νλ€!
μΈν°νμ΄μ€λ₯Ό ν΅ν΄ μ toObj
ν¨μμ λ°νκ° νμ
μ μ’ λ κ°λ¨νκ² λ§λ€ μ μλ€.
interface ToObj<T> {
a: T
b: T
}
function toObj<T extends string | number | boolean>(a: T, b: T): ToObj<T> {
return { a, b }
}
μ¬λ¬ κ°μ μ λ€λ¦μ μ¬μ©νκ³ μΆλ€λ©΄ μλμ κ°μ΄ μ¬μ© κ°λ₯νλ€.
/*
interface User<T, U, V> {
name: T,
age: U,
isValid: V
}
*/
type User<T, U, V> = { name: T; age: U; isValid: V } | [T, U, V]
type U = User<string, number, boolean>
const person1: U = { name: 'person1', age: 17, isValid: true }
const person2: U = ['person2', 19, false]
λ³΄ν΅ κ°μ²΄ νμ
μΌλ‘ νμ
μ μ§μ ν λλ μΈν°νμ΄μ€λ₯Ό μ¬μ©ν μ μλλ° person2
μ²λΌ μ§μ νκ³ μΆμ νμ
μ΄ μ λ€λ¦μ μμλ‘ κ°μ§λ λ°°μ΄ ννλΌλ©΄ type
μ°μ°μλ₯Ό ν΅ν΄ νν ννλ‘ μ§μ ν μ μλ€.
λν νμ
λ³μΉ U
μμ μ¬μ©ν κ²μ²λΌ νμ
λ³μΉμλ μ λ€λ¦μ ν¬ν¨μν¬ μ μμΌλ©° μ΄λ κ² μμ±νλ©΄ μ½λκ° κ°κ²°ν΄μ§λ€.
νμ
μ μ¬μ©μκ° μνλ 쑰건μ λ°λΌ μ§μ ν μ μλλ‘ JSμ μΌνμ°μ°μ λ¬Έλ²μ²λΌ ꡬνν μ μλ€.
μ΄λ κ² κ΅¬νν μ‘°κ±΄λΆ νμ
μ μ νΈλ¦¬ν° νμ
μ΄λΌκ³ λ λΆλ₯Έλ€.
κ°μμμλ μ¬λ¬ κ°μ§ μμ λ₯Ό λ§λλ΄€λλ° κ½€ μ μ©νλ€.
// νμ
μ΄ string λλ numberμΌ λλ§ boolean νμ
μ μ§μ νλ μ‘°κ±΄λΆ νμ
type MyType<T> = T extends string | number ? boolean : never
const a: MyType<string> = true
const b: MyType<number> = true
const c: MyType<null> = true // μλ¬: 'boolean' νμμ 'never' νμμ ν λΉν μ μμ΅λλ€.
λ΄κ° μνλ νμ
μ ν΄λΉν λλ§ νΉμ ν νμ
μ μ§μ ν μ μλ νν° μν μ νλ MyType
μ΄λΌλ μ νΈλ¦¬ν° νμ
μ΄μλ€.
// TλΌλ νμ
μμ Uμ νμ
μ μ μΈνλ μ‘°κ±΄λΆ νμ
// T νμ
μ΄ μ μ½μ‘°κ±΄μΈ U νμ
κ³Ό μΌμΉνλ©΄ never νμ
μ ν΅ν΄ ν λΉμ λ§λλ€.
type MyExclude<T, U> = T extends U ? never : T
type MyUnion = string | number | boolean | null
const a: MyExclude<MyUnion, boolean | null> = 123
const b: MyExclude<MyUnion, boolean | null> = null
// 'null' νμμ 'string | number' νμμ ν λΉν μ μμ΅λλ€.
λ§μ°¬κ°μ§λ‘ Union νμ
μ΄ μμ λ ν΄λΉ νμ
μμ νΉμ ν νμ
μ μ μΈν μ μλ MyExclude
μ νΈλ¦¬ν° νμ
μ΄λ€.
// TλΌλ κ°μ²΄ νμ
μ νΉμ μμ±μ νμ
μ 체ν¬νλ μ‘°κ±΄λΆ νμ
μ΄λ€.
type IsPropertyType<T, U extends keyof T, V> = T[U] extends V ? true : false
// keyof ν€μλλ₯Ό ν΅ν΄ κ°μ²΄ νμ
μ μμ±(ν€)λ₯Ό μΆμΆν μ μλ€.
type Keys = keyof User // 'name' | 'age'
interface User {
name: string
age: number
}
const n: IsPropertyType<User, 'name', number> = true
// User κ°μ²΄ νμ
μ 'name' μμ±μ string νμ
μ΄λ―λ‘
// false νμ
μ΄ μ§μ λλ―λ‘ μλ¬κ° λ°μνλ€.
7μ£Όμ°¨ κ³ μμ΄ μ¬μ§μ²© κ³Όμ μμ κ°μ²΄ νμ
λ΄ μμ±μ νμ
μ κ²μ¬νλ λ‘μ§μ ꡬννμλ€.
μ΄κ²μ νμ
μ€ν¬λ¦½νΈμμ μ‘°κ±΄λΆ νμ
μ ν΅ν΄ μμ½κ² ꡬνν μ μμλ€.
νμ
μ€ν¬λ¦½νΈλ₯Ό μ¬μ©νλ κΆκ·Ήμ μΈ μ΄μ κ° μ΄κ²μ΄μ§ μμκΉ
keyof
infer
ν€μλλ μ μ½ μ‘°κ±΄μ μ€μ ν λ νμ
μ€ν¬λ¦½νΈμκ² νμ
μΆλ‘ μ ν λμμ μ§μ ν λ μ°μΈλ€.
μλ μ½λλ λ°°μ΄ νμ μ΄ μ£Όμ΄μ§λ©΄ ν΄λΉ λ°°μ΄ νμ λ΄ μμμ νμ μ΄ μΌμΉν λλ§ κ°μ ν λΉν μ μκ² νλ μ‘°κ±΄λΆ νμ μ΄λ€.
type ArrayItemType<T> = T extends (infer I)[] ? I : never
const numbers = [1, 2, 3]
const a: ArrayItemType<number[]> = 123
const b: ArrayItemType<boolean> = 123
// 'number' νμμ 'never' νμμ ν λΉν μ μμ΅λλ€.
const fruits = ['Apple', 'Banana', 'Cherry']
const c: ArrayItemType<typeof fruits> = 'Mango'
const hello = () => {}
const d: ArrayItemType<typeof hello> = 'hello'
// 'string' νμμ 'never' νμμ ν λΉν μ μμ΅λλ€.
ArrayItemType
μμ μ£Όμ΄μ§ T
νμ
κ³Ό μ μ½μ‘°κ±΄μ λΉκ΅ν λ (infer I)[]
μ μ§μ νλ©΄ λ°°μ΄ νμ
μ΄κΈ΄ νλ° λ°°μ΄ μ μμμ νμ
μ T
νμ
μ λ°νμΌλ‘ μΆλ‘ ν μ μκ² ν΄μ£Όλ κ²μ΄ infer
ν€μλμ΄λ€.
μΆλ‘ κ³Όμ μ μ 리νλ©΄
a
μμλ T
νμ
μ΄ μμ νμ
μ΄ number
μΈ λ°°μ΄μ μ§μ νμΌλ―λ‘ μ μ½μ‘°κ±΄κ³Ό λΉκ΅ν λ I
κ° number
λΌκ³ μΆλ‘ μ΄ κ°λ₯νλ€. λ°λΌμ number
μΈ I
λ₯Ό λ°ννκΈ° λλ¬Έμ 123
μ ν λΉ κ°λ₯νλ€.
b
μμ T
λ₯Ό boolean
νμ
μΌλ‘ μ§μ νμ λλ μ μ΄μ λ°°μ΄ νμ
μ΄ μλλ―λ‘ μΆλ‘ ν μκ° μλ€. λ°λΌμ never
νμ
μ΄ λ°νλλ―λ‘ μλ¬κ° λ°μνλ€.
c
μμλ typeof fruits
κ° string[]
μ΄ λλ―λ‘ I
λ string
μΌλ‘ μΆλ‘ λλ€. λ°λΌμ Mango
λ₯Ό ν λΉ κ°λ₯νλ€.
d
μμλ typeof hello
κ° () => Void
λ‘ ν΄μλλ―λ‘ μ μ΄μ λ°°μ΄ νμ
μ΄ μλκΈ°μ never
νμ
μ΄ λ°νλλ€. λ°λΌμ μλ¬κ° λ°μνλ€.
μ΄μ κ°μ΄ μ μ½μ‘°κ±΄μ λΉκ΅ν λ infer
λ₯Ό μ§μ νλ©΄ μΆλ‘ ν λμμ ꡬ체μ μΌλ‘ μ€μ ν μ μλ€.
μλ SecondArgumentType
νμ
μ T
νμ
μ λ λ²μ§Έ μΈμμ νμ
μ 체ν¬νλ€.
type SecondArgumentType<T> = T extends (f: any, s: infer S) => any ? S : never
function hello(a: string, b: number) {}
const a: SecondArgumentType<typeof hello> = 123
μ¬κΈ°μ f
μ λ°νκ°μ any
νμ
μΌλ‘ μ§μ ν μ΄μ λ μ¬μ©μκ° κΆκΈνκ³ μ§μ€νλ λμμ λ λ²μ§Έ μΈμμΈ s
μ νμ
μ΄λ―λ‘ λλ¨Έμ§λ μ΄λ€ νμ
μ΄ λ€μ΄μλ λκΈ° λλ¬Έμ΄λ€.
λ°λΌμ hello
ν¨μμ λ λ²μ§Έ μΈμ b
κ° number
νμ
μ΄λ―λ‘ a
λ number
νμ
μ΄ λλ―λ‘ 123
μ ν λΉ κ°λ₯νλ€.
μ΄μ CSS κ°μ λ κ°μλ₯Ό λ£κ³ λ κ³Όμ λ νμ©μ λͺ»νλ κ²½νμ΄ μμ΄ νμ
μ€ν¬λ¦½νΈ κ°μλΆν°λ λ€μ λ°±λ¬Έμ΄ λΆμ¬μΌν
λ₯Ό μ μ©νλ€. μ§μ μ½λλ₯Ό μ³λ³΄κ³ μ΄κ² μ κ²μ λ³κ²½ν΄λ³΄λ©΄μ μ½λκ° μ΄ν΄λ λκΉμ§ λ―μ΄λ³΄λ κ°λ
μ΄ν΄κ° μ λλ κ² κ°λ€.
νμ μ€ν¬λ¦½νΈ μ€ν°λλ₯Ό λ°λ‘ μ§ννλλ° μ²« νμλ₯Ό λΆμ°Ένλ€. μ΄μ λ μ λ λ무 λ¦κ² μμ λ¦μ μ μλ²λ¦° κ²μ΄λ€. 컨λμ λ° νμ΅ μΌμ κ΄λ¦¬λ₯Ό λ μ² μ ν νμ...
νμ μ€ν¬λ¦½νΈλ₯Ό 곡λΆνλ€λ³΄λ 7μ£Όμ°¨ κ³Όμ λ μνμ λν νμ κ²μ¬λ₯Ό κΌΌκΌΌν νμμ΄μ κ·Έλ°κ° μ΄ν΄κ° μ’ λΉ¨λλ€. μΌλ₯Έ νλ‘μ νΈλ ν¬νΈν΄λ¦¬μ€μ μ μ©ν΄λ΄μΌκ² λ€.
π ν΄λΉ λ΄μ©μ 곡λΆνλ©΄μ μ 리ν κΈμ λλ€. νλ¦° λΆλΆμ΄λ μ€ν΄νκ³ μλ λΆλΆμ΄ μλ€λ©΄ νΌλλ°± λΆνλ립λλ€.