infer, never๋ง ๋ณด๋ฉด ๋๋ ค์์ง๋ ๋น์ ์ ์ํ ํ์ ์ถ๋ก - ๊ณ ๊ธ ํ์ ์ถ๋ก
infer, never๋ง ๋ณด๋ฉด ๋๋ ค์์ง๋ ๋น์ ์ ์ํ ํ์ ์ถ๋ก - ๊ณ ๊ธ ํ์ ์ถ๋ก ๊ด๋ จ
'infer, never๋ง ๋ณด๋ฉด ๋๋ ค์์ง๋ ๋น์ ์ ์ํ ํ์ ์ถ๋ก ' ๊ด๋ จ ์์์ ๋งํฌ์์ ๋ณด์ค ์ ์์ต๋๋ค.
TS์ ๊ถ๊ทน์ ์ธ ๋ชฉํ๋ ์์ ํ ๋์ ๊ณผ ์ฐธ์กฐ๋ฅผ ์คํํ๋ ๊ฒ์ ๋๋ค. ์ ๊ธ์์๋ ์ด๋ฅผ ์ํด์ ํ์ ๊ณผ ๊ทธ ๋์ ๊ด๊ณ๋ฅผ ์ ์ํ๊ณ , ์์ ํ ๋์ ์ด ๋ฌด์์ธ์ง ์ดํด๋ณด์์ต๋๋ค. ์ด ๊ธ์์๋ TS๊ฐ ์ด๋ป๊ฒ ์์ ํ์ง ์์ ๋์ ์ด๋ ์ฐธ์กฐ๋ฅผ ์ก์๋ด๋์ง ์์๋ณด๊ฒ ์ต๋๋ค.
ํ์ ๊ฒ์ฌ(type checking)
ํ์ ๊ฒ์ฌ๋, ์ด๋ค ์ฌ๋ฒ์ ๋ํ ๊ฐ์ข ๋์ /์ฐธ์กฐ/์ฐ์ฐ์ด ๊ฐ๋ฅํ์ง ํ์ธํ๋ ๊ณผ์ ์ ๋๋ค. ์ด๋ป๊ฒ ๋ณด๋ฉด ์๋ ์ฆ๋ช ์ด๋ผ๊ณ ํ ์ ์๋๋ฐ์. ๋จ์ํ ์ฆ๋ช ์์ ๊ทธ์น๋ ๊ฒ์ด ์๋๋ผ, ๊ตฌ์ฒด์ ์ผ๋ก ์ด๋ค ๋งฅ๋ฝ ํ์ ์ฌ๋ฒ์ด ๊ฐ์ง ์ ์๋ ํ์ ์ ๋ฌด์์ธ์ง๋ ์ฐพ์๋ ๋๋ค(์: ํ์ ๊ฐ๋๋ฅผ ์ํํ if๋ฌธ ๋ธ๋ก, IDE ์๋ ์์ฑ).
ํ์ ์ ์ผ๋ก ์ด๋ ์ ์ฝ ์ถฉ์กฑ ๋ฌธ์ (Constrained Satisfaction Problem, CSP)์ ์ผ์ข ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ด ๋ฌธ์ ๋ NP-์์ (NP-complete)ํ๊ธฐ ๋๋ฌธ์, ํ์ค์ ์ผ๋ก ์ปดํ์ผ๋ฌ๊ฐ ํ๊ธฐ์ ๋๋ฌด ์ด๋ ค์ด ๋ฌธ์ ์ ๋๋ค. ๋ฐ๋ผ์ tsc๋ ๊ทธ๋ฆฌ๋(greedy)ํ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํ ๊ฒ์ผ๋ก ์ถ์ ๋ฉ๋๋ค(์ค์ ๋ก ์ง์ ๋ณต์ก๋ ์ผ์ด์ค๋ฅผ ํ ์คํธํด๋ณด๋ฉด, ๋ฐฑํธ๋ํน์ ํ์ง ์๋๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค).
ํ์ ๊ฒ์ฌ๋ ์ฆ๋ช ์ด๋ค
tsc๋ ๊ฐ๋ฐ์๊ฐ ์ ๋ ฅํ ์์ค ์ฝ๋๋ฅผ ๊ธฐ๋ฐ ์ง์(knowledge base)์ผ๋ก ์ฌ์ฉํฉ๋๋ค. ์ฆ, ์ํฐ๋ฆฌ ํ์ ์ ์ฃผ๊ฑฐ๋ ์ํฐ๋ฆฌ ๋์ ์ ํ๋๋ผ๋ ๊ทธ๊ฒ์ ์ฐธ์ธ ๋ช ์ ๋ก ๊ฐ์ฃผํฉ๋๋ค. ๋์ ๊ทธ ์์ค ์ฝ๋๋ฅผ ์ ์ ๋ถ์ํ๋ฉด์ ๋ชจ์์ด ๋ฐ์ํ ๊ฒฝ์ฐ, tsc์ ๋ด์ฌํ๋ ์ฌ์ค์ ์ฐธ์ด๋ฏ๋ก ์์ค ์ฝ๋์ ์ค๋ฅ๊ฐ ์๋ค๊ณ ๊ฒฐ๋ก ์ ๋ด์ฃ .
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ ๊ฐ๋จํ ์์ ์ ์ธ๋ฌธ์ด ์๋ค๊ณ ์๊ฐํด ๋ด ์๋ค.
const x: number = 'a'
์์ ์๋ณ์ x
, ํ์
ํค์๋ number
, ๋ฌธ์์ด ๋ฆฌํฐ๋ด 'a'
๊ฐ ์๋ค์.
as const
๊ฐ ์์ผ๋ ๋ฆฌํฐ๋ด'a'
์ ํ์ ์string
์ ๋๋ค.- ์๋ณ์
x
๋number
ํ์ ์ ๋๋ค. - rvalue์ ํ์
์ lvalue์ ์๋ธํ์
์ด๋ฏ๋ก,
number
โณstring
์ ๋๋ค. - ๊ทธ๋ฐ๋ฐ ๊ณต๋ฆฌ์ ์ผ๋ก
number
โstring
์ด๋ฏ๋ก ๋ชจ์์ ๋๋ค. - tsc๋ ์์ ์ ์ธ๋ฌธ์์ ๋ฆฌํฐ๋ด์ ๊ทธ ์ฑ ์์ ๋ฌป๊ณ ๋นจ๊ฐ์ค์ ๊ธ์ต๋๋ค.
์ ๋ค๋ฆญ(generic)
์ ๋ค๋ฆญ์ด๋, ํ์
์ ํจ์์ด๊ธฐ๋ ํ์ง๋ง, ํ์
๊ฐ์ ๊ด๊ณ ๊ทธ ์์ฒด๋ฅผ ํํํ ๊ฒ์ด๊ธฐ๋ ํฉ๋๋ค(์ฌ์ค ์ํ์ ์ผ๋ก ํจ์๋ ๊ด๊ณ์ ์ผ์ข
์
๋๋ค). ์ ๋ค๋ฆญ์ ์ผ์ข
์ 1์ฐจ ๋
ผ๋ฆฌ๋ก๋ ๋ณผ ์ ์๋๋ฐ์, ์ ๋ค๋ฆญ์ ์ ๋ค๋ฆญ์ฒ๋ผ ๊ณ ์ฐจ ๋
ผ๋ฆฌ๋ ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅํฉ๋๋ค. (์: F<T> = T<number>
)
์ ๋ค๋ฆญ์ ํ์
์ธ์์ extends
ํค์๋๋ฅผ ๋ถ์ฌ์, ํ์ฉํ๋ ์ํผํ์
์ ์ง์ ํ ์ ์์ต๋๋ค.
type OnlyArray<T extends unknown[]> = ...
type X = OnlyArray<number>
// Type 'number' does not satisfy the constraint 'unknown[]'
์ ๋ค๋ฆญ์ด ํฌํจ๋ ์์ค ์ฝ๋์ ํ์ ๊ฒ์ฌ๋ 2๊ฐ์ง ์ ํ์ผ๋ก ๋๋ฉ๋๋ค.
๋ช ์์ ํ์ ์ ๋ฌ(explicit type argument passing)
๋ช ์์ ํ์ ์ ๋ฌ์ด๋ ์ ๋ค๋ฆญ ํ์ ์ธ์์ ๋ช ์์ ์ผ๋ก ํ์ ์ ๊ธฐ์ ํ๋ ํํ์ ๋๋ค. ์ ๋ฌํ ์ ๋ณด๋ฅผ ์ ์ (premise)๋ก ํ์ฉํฉ๋๋ค.
useState<{ foo?: number }>({})
์ ์ด ํ๋ฆ(control flow)์ ์ ๋ค๋ฆญ์ด ์ ์ธ๋ ์ฌ๋ฒ ๋ค์๋ถํฐ๋, ํ์ ์ ์ฌ๋ฐ๋ฆ ์ ๋ฌด์ ๊ด๊ณ์์ด ํด๋น ์ธ์๋ก ์ถ๋ก ํ ์ ์๋ ๋ชจ๋ ํ์ ์ด ๊ฒฐ์ ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด ์๋์ ์์ค ์ฝ๋๋ ์๋ชป๋ ์ธ์๋ฅผ ๋์ ํ๊ณ ์์ง๋ง, ๊ทธ๊ฒ๊ณผ ๊ด๊ณ์์ด ๋ฐํํ์ ์ ๋ค๋ฆญ์๋ง ์์กดํฉ๋๋ค.
function processList<T>(list: T[]): T[] {
// ...
}
const list = processList(new Promise())
// Argument of type 'Promise<unknown>' is not assignable to parameter of type 'unknown[]'.
list.forEach((x) => console.log(x))
// ํ์
์ค๋ฅ๊ฐ ๋ ๊ฒ๊ณผ ๋ณ๊ฐ๋ก `list`๋ `unknown[]`์ผ๋ก ๊ฐ์ฃผํ์ฌ ๊ณ์ ์งํ
ํ์ ์ธ์ ์ถ๋ก (type argument inference)
ํ์ ์ธ์ ์ถ๋ก ์ ์ ๋ค๋ฆญ์ ํ์ ์ธ์๋ฅผ ์๋ตํ ๊ฒฝ์ฐ์ ์ํํ๋ ์ถ๋ก ์ ๋๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ์์๊ฐ ์์ฃผ ๊ณ ๋ คํด์ผ ํ ๋ฐฉ์์ผ๋ก, ์ฌ์ฉ์ฑ์ ์ง๋ํ ์ํฅ์ ๋ฏธ์นฉ๋๋ค. ์ ๋ค๋ฆญ ์ธ์๋ ํ์ ์ ์ธ์ ํ์ง ์์ ์ฌ๋ฒ์ด๋, infer ํค์๋ ๋ฑ์ ์ฌ์ฉํ ๊ฒฝ์ฐ์๋ ๋์ผํ ์๋ฆฌ๊ฐ ์ ์ฉ๋ฉ๋๋ค.
์ด ๋ฐฉ์์ tsc๊ฐ ์ ์ ๋ถ์์ผ๋ก ์ป์ด๋ธ ์ ๋ณด๋ฅผ ํ ๋๋ก, ์ต๋ํ ์ธ์๋ฅผ ์ถ๋ก ํฉ๋๋ค. ๋ง์ฝ ์ถ๋ก ์ ์คํจํ ๊ฒฝ์ฐ unknown
์ผ๋ก ๊ฐ์ฃผํฉ๋๋ค. ์ด ์๊ณ ๋ฆฌ์ฆ์ ๋ช
์์ ์ผ๋ก ์๋ ค์ ธ ์์ง ์์ผ๋ฉฐ, ๋๋ก๋ ์ผ๊ด์ฑ์ด ์๊ธฐ๋ ํฉ๋๋ค. ๋ง์ ๊ฒฝ์ฐ tsc๋ ๊ฐ์ฅ ๋น๊ด์ ์ด๊ณ ๋ณด์์ ์ธ ๊ด์ ์ผ๋ก ํ์
์ ์ถ๋ก ํฉ๋๋ค. ๋ํ ๊ทธ๋ฆฌ๋ํ๊ณ ํด๋ฆฌ์คํฑํ ์ถ๋ก ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๋ฉฐ, tsc๊ฐ ์
๋ฐ์ดํธ๋๋ฉด์ ๋์์ด ์ํญ ๋ฐ๋๊ธฐ๋ ํ๋ ์ฃผ์๊ฐ ํ์ํฉ๋๋ค.
function f<T>(value: Promise<T>): T
function f<T>(value: T): T[]
function f<T>(value: number): string
function f(value: any): any { ... } // ๊ตฌํ์ฒด
const x = f(3) // x์ ํ์
์ number[]
์ ์์์์ f(3)
ํธ์ถ๋ฌธ์ ๋ง์กฑํ๋ ๊ฐ์ฅ ์ฒซ ๋ฒ์งธ ์๊ทธ๋์ฒ๋ function f<T>(value: T)
์
๋๋ค. number
๋ผ๋ ๊ตฌ์ฒด์ ์ธ ํ์
์ด ์๋์ ์์ง๋ง, ์ด๋ฏธ ๋ง์กฑํ ์๊ทธ๋์ฒ๊ฐ ์์ผ๋ฏ๋ก ๋ฌด์ํฉ๋๋ค.
์กฐ๊ฑด๋ถ ํ์ (conditional type)
์กฐ๊ฑด๋ถ ํ์
์ด๋ ์ ๋ค๋ฆญ ์ ์๋ฌธ์์ ํน์ ํ์
์ด ๋ค๋ฅธ ํ์
์ ์๋ธํ์
์ธ์ง ํ์ธํ ๋ค ๋ถ๊ธฐํ๋ ๊ตฌ๋ฌธ์
๋๋ค. infer
์ ๋ฐ์ ํ ์ฐ๊ด์ด ์์ต๋๋ค.
type IsNever<T> = [T] extends [never] ? true : false
์ด๋ extends ... infer
ํค์๋๋ก, ํน์ ํ์
ํํ์์ ๋ง์กฑํ๋ ๊ฐ์ฅ ์์ ์ํผํ์
์ ์ถ๋ก ํ ์๋ ์์ต๋๋ค.
type GetElement<T> = T extends (infer R)[] ? R : never
type ShouldNumber = GetElement<number[]>
// number[]์ ์ํผํ์
์ (number | string)[], unknown[], number[] | string ๋ฑ ๋ค์ํ์ง๋ง
// ๊ฐ์ฅ ์์ ์ํผํ์
์ number[]์ด๋ฏ๋ก, R์ number๋ก ์ถ๋ก ๋ฉ๋๋ค.
์ฃผ์ ์ฌํญ
์ธ์์ T
์ ๋ํ ์ ๋ณด๊ฐ ํ๋๋ ์๋ ๊ฒฝ์ฐ, ํญ์ ๋ชจ๋ ๋ถ๊ธฐ์ ๊ฒฐ๊ณผ๋ฅผ ํฉ์ฐ์ฐํ์ง๋ ์๋๋ค๋ ๊ฒ์ ์ฃผ์ํด์ผ ํฉ๋๋ค.
๊ฐ๋ น ์๋์ ์ฝ๋๋ ์ผํ ์ดํด๊ฐ ๋์ง ์์ ์ ์๋๋ฐ์, x โฒ T
์ด๋ฉด์ x โฒ string
์ด๋ผ๊ณ ํด์ T โฒ string
์ด๋ผ๋ ๋ณด์ฅ์ด ์๊ธฐ ๋๋ฌธ์
๋๋ค. ์ด ์ํฉ์์ T
์ ๊ดํด์ ์ด๋ ํ ์ ์ ๋ ํ ์ ์๊ณ , ๊ฒฐ๊ณผ์ ์ผ๋ก F<T>
๋ ๊ฒฐ์ ์ ๋ชปํ๋ ์ํฉ์ด ๋ฉ๋๋ค. ์์์ ์ผ๋ก ์๊ฐํ๋ฉด true | false
๋ boolean
์ ๋ฐํํ ๊ฒ ๊ฐ์ง๋ง, ์ ์ด๋ 5 ๋ฒ์ ๊น์ง์ tsc๋ ๊ทธ๋ฅ ํ์
์ค๋ฅ๋ฅผ ๋ด๋ฒ๋ฆฝ๋๋ค.
type F<T> = T extends string ? true : false
function foo<T>(x: T): F<T> {
if (typeof x === 'string') {
return true // Type 'boolean' is not assignable to type 'F<T>'
}
return false // Type 'boolean' is not assignable to type 'F<T>'
}
์กฐ๊ฑด๋ถ ํ์ ์ ๋ถ๋ฐฐ ๋ฒ์น(distributive law)
์กฐ๊ฑด๋ถ ํ์
์๋ ํน์ํ ๊ธฐ๋ฅ์ด ์์ต๋๋ค. ๋ฐ๋ก extends
ํค์๋๊ฐ ํฉ์งํฉ์ ๋ํ ๋ถ๋ฐฐ๋ฅผ ์ํํ๋ค๋ ์ ์
๋๋ค. ๋ค์ ๋ ์ ๋ค๋ฆญ์ ๋ณด๋ฉด ๋จ์ ์ผ๋ก ์ดํดํ ์ ์์ต๋๋ค.
type F<T> = T[]
type G<T> = T extends unknown ? T[] : never
type T1 = F<string | number> // (string | number)[]
type T2 = G<string | number> // string[] | number[]
unknown
์ ํญ์ ๋ชจ๋ ํ์
์ ์ํผํ์
์ด๊ธฐ ๋๋ฌธ์, G
๋ ๋ฌป์ง๋ ๋ฐ์ง์ง๋ ์๊ณ ๋ฐฐ์ด์ ๋ฐํํฉ๋๋ค. ๊ทธ๋ฐ๋ฐ F
๋ ๊ฐ๋ณ ์์๊ฐ ํฉ์งํฉ์ธ ๋ฐ๋ฉด, G
๋ ๊ฐ๋ณ ์์๋ ๋ถ๋ฆฌ๋๊ณ ๊ทธ ๊ฒฐ๊ณผ๊ฐ ํฉ์งํฉ์ด ๋ฉ๋๋ค. ์ด ์ฌ์ค์ ๊ณ ๊ธ ํ์
์ ์ค๊ณํ ๋ ๋งค์ฐ ์ค์ํ๊ฒ ์์ฉํฉ๋๋ค. ๊ฒฝ์ฐ์ ๋ฐ๋ผ์๋ ์ ์ฑ์ง์ ์ต์ ํด์ผ ํ ๋๋ ์๋๋ฐ์, ๊ทธ๋ด ๋ ํํ๋ก ๊ฐ์ธ์ฃผ๋ฉด ๋ฉ๋๋ค.
์กฐ๊ฑด๋ถ ํ์
์ ์์๋ฅผ ๋ค ๋ ํน์ ํ์
์ด never
์ธ์ง ํ์ธํ๋ IsNever
๋ฅผ ๋ค์ ๋ณด์ธ์. ๋ถ๋ฐฐ ๋ฒ์น์ ์ต์ ํ๊ณ ์์ต๋๋ค. ์ ๊ทธ๋ด๊น์?
type WrongIsNever<T> = T extends never ? true : false
type IsItTrue = WrongIsNever<never> // never
๋ฐ๋ก never
๊ฐ ๊ณต์งํฉ์ ์ฑ์ง์ ๊ฐ๊ธฐ ๋๋ฌธ์
๋๋ค. ์กฐ๊ฑด๋ถ ํ์
์ T
๋ฅผ ๋์์ผ๋ก ํฉ์งํฉ์ ๋ํ ๋ถ๋ฐฐ๋ฅผ ์ํํฉ๋๋ค. ์ฆ, ๋ด๋ถ์ ์ผ๋ก ํ์
์ธ์๋ฅผ ๋์์ผ๋ก ํ๋์ฉ map
์ ์ํํ๋ ๊ฒ๊ณผ ์ ์ฌํ ๋์์ ํฉ๋๋ค. ๊ทธ๋ฐ๋ฐ never
๋ ๋น ๋ฐฐ์ด, ํน์ ๊ณต์งํฉ๊ณผ ๋ค๋ฅผ ๋ฐ๊ฐ ์์ด, ํด๋น ์ฐ์ฐ์ ์์ ์ํํ์ง ์์ต๋๋ค. ๊ทธ๋์ true
๋ false
๋ ์๋, ๋น ํ์
์ธ never
๊ฐ ๋ฐํ๋ ๊ฒ์
๋๋ค. ๊ทธ๋ฌ๋ ํํ๋ก ๊ฐ์ ๊ฒฝ์ฐ, [never]
๋ ์์ฐํ ๋น์ด์์ง ์์ ํ์
์ด๊ณ , [...]
๊ฐ 1๊ฐ ์๋ ํ์
์ ํฉ์งํฉ์ด๋ฏ๋ก ์๋ํ ๋๋ก ์ถ๋ก ํ ๊ฒ์
๋๋ค.
๋ง์น๋ฉฐ
TS๊ฐ ์ด๋ป๊ฒ ์์ ํ์ง ์์ ๋์ ์ด๋ ์ฐธ์กฐ๋ฅผ ์ก์๋ด๋์ง ์์๋ณด์์ต๋๋ค. ๋ค์ ๊ธ์์๋ ์ง๊ธ๊น์ง ๋ค๋ฃฌ ๋ด์ฉ์ ํ ๋๋ก ์์ฉ ๋ฌธ์ ๋ฅผ ํ์ด ๋ณด๊ฒ ์ต๋๋ค.
infer, never๋ง ๋ณด๋ฉด ๋๋ ค์์ง๋ ๋น์ ์ ์ํ ํ์ ์ถ๋ก ์๋ฆฌ์ฆ