infer, never๋ง ๋ณด๋ฉด ๋๋ ค์์ง๋ ๋น์ ์ ์ํ ํ์ ์ถ๋ก - ๊ธฐ์ด ํ์ ์ด๋ก
infer, never๋ง ๋ณด๋ฉด ๋๋ ค์์ง๋ ๋น์ ์ ์ํ ํ์ ์ถ๋ก - ๊ธฐ์ด ํ์ ์ด๋ก ๊ด๋ จ
'infer, never๋ง ๋ณด๋ฉด ๋๋ ค์์ง๋ ๋น์ ์ ์ํ ํ์ ์ถ๋ก ' ๊ด๋ จ ์์์ ๋งํฌ์์ ๋ณด์ค ์ ์์ต๋๋ค.
TypeScript(์ดํ TS)๋ JavaScript(์ดํ JS)์ ๋ฐํ์ ์ทจ์ฝ์ฑ์ ๊ทน๋ณตํ๊ณ ์, ํ์
์ด๋ก ์ ๋์
ํ์ฌ ์ ์ ๋ถ์์ ์คํํ ์ธ์ด์
๋๋ค. ํ์ง๋ง ๋๋ค์์ ์น ์ ํ๋ฆฌ์ผ์ด์
๊ฐ๋ฐ ๊ณผ์ ์์ TS์ ๊ธฐ๋ฅ์ ๊น๊ฒ ์ฌ์ฉํ ์ผ์ ๋๋ญ
๋๋ค. ๊ธฐ๊ปํด์ผ ์ธํฐํ์ด์ค๋ฅผ ์ ์ธํ๊ฑฐ๋, Record
๋ฑ์ ์ ํธ๋ฆฌํฐ ํ์
์ผ๋ถ๋ฅผ ์ฐ๋ ์ ๋์
๋๋ค.
๊ทธ๋ฌ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ฐ๋ฐํ๋ค๋ฉด ์ด์ผ๊ธฐ๋ ๋ฌ๋ผ์ง๋๋ค. ์ฌ์ค์ TS๊ฐ ํ์๊ฐ ๋ ์๋์ ์์, ์ฌ์ง์ด TS๋ฅผ ์ฌ์ฉํ์ง ์๋ ์ฌ๋์กฐ์ฐจ IDE์ ํ์ ์ถ๋ก ๊ธฐ๋ฅ ์ํ๋ฅผ ๋ฐ๊ณ ์์ ์ ๋๋ก, ํ์ ์ ๋นผ๋์ ์ ์๋ ๊ด์ฌ์ฌ๊ฐ ๋์์ต๋๋ค. ํ์ ์ถ๋ก ์ด ์ ๋๋ก ์ด๋ฃจ์ด์ง์ง ์์ผ๋ฉด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ฌ์ฉ์ฑ์ ํ์ ํ ๋จ์ด์ง๋๋ค.
์ ๋๋ก ๋ ํ์ ์ถ๋ก ์ ์คํํ๋ ค๋ฉด, ์ํ์ ์ผ๋ก ํ์ ์ด๋ก ์ ์ดํดํ๊ณ ์ ์ฉํ ์ ์์ด์ผ ํฉ๋๋ค. ์ด ๊ธ์ ์๋ฆฌ์ฆ๋ TS๋ฅผ ๊ดํตํ๋ ํ์ ์ถ๋ก ์ ์๋ฆฌ๋ฅผ ๊ธฐ์ด ํ์ ์ด๋ก ๊ณผ ๊ณ ๊ธ ํ์ ์ถ๋ก ์ผ๋ก ๋๋์ด ์ดํด๋ณด๊ณ , ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ฐ๋ฐ์๊ฐ ๊ฒฝํํ ๋ฒํ ์ค์ ๋ฌธ์ ๋ฅผ ํ์ด๋ด ๋๋ค. ๋จ๋ฒ์ ์ฝ๊ธฐ์ ๋ฒ ์ฐฐ ์ ์์ต๋๋ค. ์ฌ์ ๊ฐ ์๋ค๋ฉด ์ฒ์ฒํ ์๋ฏธํ์๋ฉด์ ํ์ตํ์๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
์ด ๊ธ์ ์ฝ์ผ๋ฉด ์ข์ ๋ถ
- JS ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ฐ๋ฐ์
- ํ์ ์ด ์ถ๋ก ๋๋ ์๋ฆฌ๊ฐ ๊ถ๊ธํ ๊ฐ๋ฐ์
- infer ๋ฑ์ผ๋ก ๊ณ ๊ธ ์ ๋ค๋ฆญ์ ์ฌ์ฉํด ๋ณด๊ณ ์ถ์ ๊ฐ๋ฐ์
ํ์ ์ด๋ก ์ ์ญ์ฌ์ ๋ฐฐ๊ฒฝ
ํ์ ์ด๋ก ์ ๊ทผ๊ฐ์๋ ์ํ๊ธฐ์ด๋ก (foundation of mathematics)์ด ์์ต๋๋ค. 20์ธ๊ธฐ ์ด์ ๊น์ง๋ง ํ๋๋ผ๋ ์ํ์ ์๊ฐ๋ณด๋ค ์๋ฐํ์ง ์์๋๋ฐ์, 1908๋ ๋ฌ์ ์ ์ญ์ค์ด ๋ฐ๊ฒฌ๋๋ฉฐ ๋ชจ๋ ์ํ์ ๊ธฐ์ด์ธ ์งํฉ์ด ํ๋ค๋ฆฝ๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ ์ ZFC ๊ณต๋ฆฌ๊ณ, ๊ดด๋ธ์ ๋ถ์์ ์ฑ ์ ๋ฆฌ ๋ฑ์ ์๋ฐํ ๊ณ ์ฐฐ์ด ๊ณ์๋์์ต๋๋ค.
ํ์ ์ด๋ก ์ ์๋ํ ๊ณผํ์ ์ค ํ๋์ธ ์จ๋ฐ์กฐ ์ฒ์น(Alanzo Church)๊ฐ ๋๋ค ๋์(lambda calculus)๋ฅผ ๊ณ ์ฐฐํ๋ฉด์ ํ์ํ์ต๋๋ค. ์ฒ์น ์ธ์๋ ๋ง์ ์ํ์๊ฐ ์ ์ฌํ ์๋๋ฅผ ํ๊ณ , ๋น๊ต์ ์ต๊ทผ๊น์ง๋ ํ๊ณ์์ ๋ค๋ค์ง๋ ์ฃผ์ ๋ผ๊ณ ํฉ๋๋ค. ์๋ฆฌ์ฒ ํ์ ์ผ๋ก ๋ ์์ธํ ๋ด์ฉ์ ์๊ณ ์ถ๋ค๋ฉด ์คํ ํฌ๋ ๋ํ์ ์๋ฃ๋ฅผ ์ฐธ๊ณ ํด ์ฃผ์ธ์.
TypeScript์ ํ์ ์ด๋ก
TS 1.8๊น์ง๋ ๊ณต์ ๋ฌธ์๊ฐ ์กด์ฌํ์ผ๋, ์ดํ Microsoft๊ฐ ๋ฌธ์ ์ ์ง๋ณด์๋ฅผ ํฌ๊ธฐํ์ต๋๋ค. ๋๋ฌธ์ ํ์ฌ TS์ ์ฌ์์ TypeScript ์ปดํ์ผ๋ฌ(์ดํ tsc)์ ๊ตฌํ ๊ทธ ์์ฒด๊ฐ ๋ ์ํฉ์ ๋๋ค. ๊ฒ๋ค๊ฐ ๊ตฌ๋ฒ์ ๋ฌธ์์๋ ์ผ๊ด์ฑ ์๋ ํ์ ์ถ๋ก ์๊ณ ๋ฆฌ์ฆ์ ๋ํ ์ ๋ณด๋ ์ฐพ์๋ณด๊ธฐ๊ฐ ์ด๋ ต์ต๋๋ค.
๋ฐ๋ผ์ ์ด ๊ธ์์๋ tsc๋ฅผ ๋ธ๋๋ฐ์ค๋ก ๊ฐ์ฃผํ๊ณ , ์ํ์ ์ผ๊ด์ฑ๊ณผ ์คํ์ ๊ทผ๊ฑฐ๋ก ์ป์ ๋ด์ฉ์ ์์ ํฉ๋๋ค. ๋ง์ฝ ์ด ๊ธ์ ๋ด์ฉ๊ณผ ์ถฉ๋ํ๋ ์ฌํญ์ด ์๋ค๋ฉด, TS ์ ์ฅ์์ Discussion์์ ๋ ผ์ํ๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค. ์๊ฐ์ด ์ง๋ ๋ฒ์ ์ด ๋ฐ๋๋ฉด ๋์์ด ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค. ๋ํ ์ด ๊ธ์์๋ ์ค์ฉ์ ์ธ ๊ฐ๋ฐ์ ๋๊ธฐ ์ํด, ์๋ฐํจ์ ๋ค์ ํฌ๊ธฐํ๊ณ ๊ฐ๊ฒฐํ ์ค๋ช ์ ๋ชฉํ๋ก ํ์์ ์๋ฆฝ๋๋ค.
ํ์ ์ด๋
ํ์ ์ ๋ค์๊ณผ ๊ฐ์ด ์ ์ํ ์ ์์ต๋๋ค.
์ด๋ค ์ฌ๋ฒ(symbol, โ๋ณ์๋ช )์ ์ฎ์ธ(binded) ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์กด์ฌํ ์ ์๋ ๊ฐ(value)์ ์งํฉ๊ณผ ๊ทธ ๊ฐ๋ค์ด ๊ฐ์ง ์ ์๋ ์ฑ์ง(properties)
๊ตฌ์ฒด์ ์ธ ์์๋ฅผ ํตํด ์์๋ด ์๋ค. ์๋๋ ๊ฐ 3.141592๊ฐ ํ์ number์ ์ํ๋ค๋ ๊ฒ์ ํํํ ๊ฒ์ ๋๋ค.
3.141592 : number
- number ํ์
์ผ๋ก ์ฎ์ธ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์๋
'foo'
,null
๊ฐ์ ๊ฐ์ ์ฌ ์ ์์ต๋๋ค. - number ํ์
์ ๋ง์
, ๊ณฑ์
๋ฑ์ ์ฐ์ ์ฐ์ฐ์ ํ ์ ์์ผ๋ฉฐ,
toString
,toFixed
๋ฑ์ ์์ฑ์ด ์์ต๋๋ค.
ํ์ ๊ณผ ํ์ ๊ฐ์๋ ๊ด๊ณ๊ฐ ์กด์ฌํ๋๋ฐ์, ํ์ A๊ฐ ๋ค์์ ๋ง์กฑํ ๋ ํ์ B์ ์๋ธํ์ ์ด๋ผ๊ณ ํฉ๋๋ค.
ํ์ B์ ๋ชจ๋ ์์ฑ์ด A์๋ ์์ ๊ฒ
์์ฑ์ด ๋ฌด์์ด๋, primitive ํ์
์ผ ๋ ์ด๋ป๊ฒ ๋น๊ตํ ๊ฒ์ด๋ ํ๋ ๊ฒ์ ๋ค์์ ์ดํด๋ณด๊ณ ์ง๊ธ์ ๊ฑฐ์์ ์ธ ๊ฐ๋
๋ง ์ตํ๋๊ฒ ์ต๋๋ค. ์๋๋ ํ์
{ x: number; y?: string }
์ด { x: number }
์ ์๋ธํ์
์์ ํํํ ๊ฒ์
๋๋ค.
{ x: number; y?: string } โฒ { x: number }
ํ์ ์ ๋ถ๋ถ์์์งํฉ
์์ ์ดํด๋ณด์๋ฏ, ํ์ ์ ๋น๊ต ๊ฐ๋ฅํฉ๋๋ค. ๋น๊ต ๊ฐ๋ฅํ ์งํฉ ์ค ๊ฐ์ฅ ์ต์ํ ๊ฒ์ผ๋ก ์ค์(real number)๊ฐ ์๋๋ฐ์. ํ์ ์ ๋์ ๊ด๊ณ์ ์ค์์ ๋์ ๊ด๊ณ๋ ์ฝ๊ฐ ๋ค๋ฆ ๋๋ค.
๋ชจ๋ ์์์ ๋ ์ค์๋ ๋ค์์ ๋ ์ค ์ต์ํ ํ๋๋ฅผ ๋ง์กฑํฉ๋๋ค.
ํน๋ณํ a โฅ b์ด๋ฉด์ a โค b์ธ ๊ด๊ณ๋ฅผ a = b๋ผ๊ณ ํฉ๋๋ค. ์ด๋ฐ ์งํฉ์ ์ ์์์งํฉ(totally ordered set)์ด๋ผ๊ณ ํฉ๋๋ค. ์๋ฐํ๊ฒ๋ ๋ช ๊ฐ์ง ์กฐ๊ฑด์ด ๋ถ์ง๋ง, ์ง๊ธ์ ์ค์ํ์ง ์์ผ๋ ์ฐธ๊ณ ๋ง ํด์ฃผ์ธ์.
ํ์ ์ ์กฐ๊ธ ๋ค๋ฆ ๋๋ค. ๋ค์ 4๊ฐ์ง ์ค ํ๋๋ง ๋ง์กฑํฉ๋๋ค.
- ์ด๋ฉด์
ํน๋ณํ a โณ b ์ด๋ฉด์ a โฒ b ์ธ ๊ฒฝ์ฐ๋ฅผ a โ b ๋ผ๊ณ ํํํ๊ฒ ์ต๋๋ค. ์ฌ๊ธฐ์ ์ค์ํ ์ ์ a โณ b๊ฐ ์๋๋ผ๊ณ ํด์ a โฒ b๋ผ๊ณ ํ ์ ์๋ค๋ ์ ์ ๋๋ค. ์ด๋ฐ ์งํฉ์ ๋ถ๋ถ์์์งํฉ(partially ordered set)์ด๋ผ๊ณ ํฉ๋๋ค.
๊ตฌ์ฒด์ ์ธ ์์๋ฅผ ๋ณด๊ณ ๊ธฐํธ๋ฅผ ์ฒดํํด ๋ณด์ธ์.
number โณ 42
symbol | string โฒ number | symbol | string
{ x?: number } โ { x: number | undefined }
number โ { x: number }
ํ์ ๊ณผ ๊ฐ์ ๋์
๋ฌ๊ธ์์ด ๋์ ๋น๊ต๋ฅผ ์ ๋ฐฐ์ ๋๋, ๋ฐ๋ก ๊ฐ์ ๋์ ํ๋ ์กฐ๊ฑด์ ์ ์ํ๊ธฐ ์ํด์์ ๋๋ค. TS๋ ์์ ํ ๋์ ๊ณผ ์ฐธ์กฐ๋ฅผ ์คํํ๋ ๋ฐฉ๋ฒ์ผ๋ก์ ํ์ ์ด๋ก ์ ์ฌ์ฉํฉ๋๋ค.
๋ ์ฌ๋ฐ๋ฅธ ๋์
๋ค์ ์ฝ๋๋ฅผ ํ๋์ฉ ๋ณผ๊น์?
const x: number = 42
// number โณ number์ด๋ฏ๋ก, ๋์
๊ฐ๋ฅ
const x: string = 42
// string โ number์ด๋ฏ๋ก, ๋์
๋ถ๊ฐ๋ฅ
const x: string | number = 42
// string | number โณ number์ด๋ฏ๋ก, ๋์
๊ฐ๋ฅ
์ด๋ ๊ฒ ๋์ํ๋ ์ด์ ๋, ์๋ธํ์
์ ๋ฐ๋์ ์ํผํ์
์ด ๊ฐ์ง๋ ์ฑ์ง์ ๊ฐ๊ธฐ ๋๋ฌธ์
๋๋ค. ์ฆ, ์์ฑ์ ๋ํ ์์ ํ ์ฐธ์กฐ๋ฅผ ํ ์ ์์ต๋๋ค. null
์ด๋ undefined
๋ฅผ ๋์์ผ๋ก .toString()
๋ฑ์ ์ฐธ์กฐ๋ฅผ ํ๋ฉด ๋ฐํ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ฃ ? ํ์
์ด๋ก ์ ์ด๋ฅผ null
ํ์
์ด toString
์ด๋ผ๋ ์์ฑ์ ๊ฐ์ง์ง ์์๊ธฐ ๋๋ฌธ์ผ๋ก ๋ณธ ๊ฒ์
๋๋ค.
ํ์ ์ ์ข ๋ฅ์ ๋ฐ๋ฅธ ๋์ ๋น๊ต
์์์๋ ๊ฐ๋จํ๊ฒ ์๊ฐํ์ง๋ง, ์ด์ ์ ์์ผ๋ก ํ์ ์ ๋์ ๋น๊ต๋ฅผ ์ด๋ป๊ฒ ํ๋์ง ์์๋ด ์๋ค.
์์ ํ์ (primitive type)
์์ ํ์ ์ด๋ ๋ค์ 6๊ฐ์ง๋ฅผ ๋งํฉ๋๋ค.
boolean
number
string
symbol
null
undefined
์ด๋ค์ ๊ณต๋ฆฌ์ ์ผ๋ก ์ ์ํฉ๋๋ค. null
์ ์ ์ธํ๋ฉด, JS์ ์กด์ฌํ ์ ์๋ ๊ฐ์ typeof
๋ฅผ ์ํํ์ ๋ ๊ฒฐ๊ณผ๊ฐ ์ ์ค ํ๋๋ผ๋ฉด ๊ทธ๊ฒ์ด ๊ณง ์์ ์ ํ์
์ด๋ฆ์
๋๋ค. ์๋ฅผ ๋ค์ด typeof 3.141592 === 'number'
์ด๋ฉด ํด๋น ๋ฆฌํฐ๋ด์ number
ํ์
์
๋๋ค.
์ด๋ค์ ์๊ธฐ ์์ ๊ณผ๋ ์๋ธํ์ ๊ด๊ณ์ด๊ณ , ๋ค๋ฅธ ํ์ ๊ณผ๋ ๋ฌด๊ด๊ณ์ ๋๋ค.
์ฐธ๊ณ ๋ก TS์์๋ null
์ ๊ฐ์ฒด(object
)์ ์๋ธํ์
์ผ๋ก ๊ฐ์ฃผํ์ง ์์ต๋๋ค. ์๋ํ๋ฉด null
์ ์ฐธ์กฐํ ์ ์๋ ์์ฑ์ด ํ๋๋ ์๊ธฐ ๋๋ฌธ์
๋๋ค. JS์์ ์ญ์ฌ์ ์ธ ์ด์ ๋ก ์ธํด typeof null === 'object'
์ธ ๊ฒ๊ณผ ๋์กฐ์ ์
๋๋ค.
๋ฆฌํฐ๋ด ํ์ (literal type)
๋ฆฌํฐ๋ด ํ์
์ด๋ ์ด๋ค ์ํผํ์
์ ์ํ ๊ฐ '1๊ฐ'๋ง์ผ๋ก ๊ตฌ์ฑ๋ ํ์
์
๋๋ค. ์๋ฅผ ๋ค์ด number โณ 6
๊ณผ ๊ฐ์ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
์ฐธ๊ณ ๋ก ๋๋ถ๋ถ์ ๊ฒฝ์ฐ, ๋ฆฌํฐ๋ด์ ์ฐ๋ฉด ํด๋น ์ฌ๋ฒ์ ์์ ํ์
์ผ๋ก ๊ฐ์ฃผ๋ฉ๋๋ค. ๊ฐ์ ๋ก ๋ฆฌํฐ๋ด ํ์
์ผ๋ก ๋ณํํ ํ์๊ฐ ์๋ค๋ฉด as const
ํค์๋๋ฅผ ๋ถ์ด๋ฉด ๋ฉ๋๋ค.
๊ฐ์ฒด ํ์ (object type)
๊ฐ์ฒด ํ์ ์ ๊ฐ๋ณ ์์ฑ์ ๋ฐฉํฅ์ด ์ผ์นํ ๋, ์ ์ฒด์ ๋์ ๋ฐฉํฅ๋ ๋๊ฐ์ด ๋ฐ๋ผ๊ฐ๋๋ค.
๋ง์ด ์ด๋ ค์ฐ๋ ๊ตฌ์ฒด์ ์ธ ์์๋ฅผ ๋ณด๊ฒ ์ต๋๋ค. ์ฌ๊ธฐ 2๊ฐ์ง ํ์ ์ด ์์ต๋๋ค.
type A = {
x: number
y?: string
z: boolean
}
type B = {
x: number
z: false
a: 'foo'
}
tsc๋ A โณ B์ธ์ง ๊ถ๊ธํด ํฉ๋๋ค. ์ด๋ ์ฐ๋ฆฌ๋ ํ์ ์ ์ ์์์ ์ ์ ๋ณด์๋ '์ํผํ์ ์ ๋ชจ๋ ์์ฑ'์ ๋ฐ์ง๊ธฐ ์์ํฉ๋๋ค. A๊ฐ ์ํผํ์ ์ธ์ง ๋ฌผ์ด๋ดค์ผ๋, A์ ์์ฑ์ ๋์ดํด์ผ๊ฒ ์ง์?
A๋ x
, y
, z
๋ผ๋ ์์ฑ์ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, ๊ฐ๊ฐ number
, string | undefined
, boolean
์ ํ์
์ผ๋ก ๊ฐ์ต๋๋ค. ์ด์ ๊ฐ ์์ฑ ์ด๋ฆ์ ๋ํด, B์์ ํด๋น ์์ฑ์ด ๋ฌด์จ ํ์
์ธ์ง ํ์ธํฉ๋๋ค. ์ด๋ฅผ ๊ฐ๊ฒฐํ๊ฒ ๋ํ๋ด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
A['x'] = number โณ number = B['x']
A['y'] = string | undefined โณ undefined = B['y']
A['z'] = boolean โณ false = B['z']
B['a']
๋ ์ ๋น๊ตํ์ง ์๋๊ณ ์? ์ํผํ์
์ธ A
์๋ a
๋ผ๋ ์์ฑ์ด ์๊ธฐ ๋๋ฌธ์
๋๋ค. B
ํ์
์ ๊ฐ์ A
ํ์
์ ๋์
ํ ์ ์๊ณ , A
ํ์
์ ํตํด์ a
์์ฑ์ ์ ๊ทผํ์ง ๋ชปํฉ๋๋ค. ๋ฐ๋ผ์ a
์ ํ์
์ ์ค์ํ์ง ์์ต๋๋ค.
์ด๋ ๊ฒ ์ด๋ค ๋ ์์ ๊ด์ฌ์ฌ์์์ ๋ฐฉํฅ์ด ๊ฑฐ์์ ์ธ ๋์ ๊ด๊ณ ๋ฐฉํฅ๊ณผ ์ผ์นํ ๋ ๊ทธ ์ฑ์ง์ ๊ณต๋ณ์ฑ(covariance)์ด๋ผ๊ณ ํฉ๋๋ค. ๊ฐ์ฒด ํ์ ์ ๋์ ๊ด๊ณ๋ ๊ฐ ํ์ ์ด ๊ฐ์ง ์ฑ์ง์ ๋ํ์ฌ ๊ณต๋ณ์ ์ ๋๋ค. ๋ง์ฝ ํ๋๋ผ๋ ๋ฐฉํฅ์ด ์ผ์นํ์ง ์์ ๊ฒฝ์ฐ, ๋ ํ์ ์ ๋ฌด๊ด๊ณ์ ๋๋ค.
๋ฐฐ์ด/ํํ ํ์
๋ฐฐ์ด๋ ๊ฐ์ฒด์ ๋๋ค. ํํ์ ๋ฐฐ์ด์ ์ผ์ข ์ด์ฃ . ๋ฐ๋ผ์ ์ด๋ค์ ๊ฐ์ฒด์ ๋์ผํ ์๋ฆฌ๊ฐ ์ ์ฉ๋ฉ๋๋ค.
๋ฐฐ์ด์ ํ์ ์ ๊ฐ๋ณ ์์ ํ์ ์ ๋ํ์ฌ ๊ณต๋ณ์ ์ ๋๋ค.
๊ฐ์ฒด์ ๋ฐฐ์ด์ ์ฐจ์ด๊ฐ ์๋ค๋ฉด, number
๋ฅผ ํค ๊ฐ์ผ๋ก ๊ฐ๋๋ค๋ ์ ์
๋๋ค. ๋ค๋ง keyof string[]
์ด number
๋ฅผ ์ง์ ๋ฐํํ์ง๋ ์๋๋ฐ, ๋ฐฐ์ด์๋ concat
๊ณผ ๊ฐ์ ๋ค๋ฅธ ์์ฑ๋ ๋ง์ด ์๊ธฐ ๋๋ฌธ์
๋๋ค. ํ์ง๋ง ๋ช
๋ฐฑํ๊ฒ keyof string[] โณ number
๋ ๋ง์ต๋๋ค.
ํํ ํ์
์ length
๊ฐ number
์ ๋ฆฌํฐ๋ด ํ์
์ด๋ผ๋ ์ ์ด ๋ฐฐ์ด๊ณผ ๋ค๋ฆ
๋๋ค. ๋ง์ฝ length
๋ฒ์ ๋ฐ์ ์ธ๋ฑ์ค๋ฅผ ์ฐธ์กฐ ์, ํ์
์ค๋ฅ๋ฅผ ๋ฐ์์ํค๋ฉฐ ํด๋น ์ฐธ์กฐ๊ฐ์ any
๋ก ์ถ๋ก ํฉ๋๋ค.
ํค ํ์ (keyof)
ํค ํ์
์ด๋ ๊ฐ์ฒด ํ์
์ ์์ฑ ์ด๋ฆ์ ํฉ์งํฉ(|
)์ผ๋ก ์ด๋ฃจ์ด์ง ํ์
์
๋๋ค.
keyof { x: number; y?: string; z: boolean }
โ 'x' | 'y' | 'z'
๋ชจ๋ ํค ํ์
์ number | string | symbol
์ ์๋ธํ์
์
๋๋ค.
ํจ์ ํ์
ํจ์ ํ์ ์ ๋ฐํํ๊ณผ ์ธ์์ ํ์ ๋ ๊ฐ์ง ์์๊ฐ ์กฐํฉ๋ ๊ฒ์ด๋ฉฐ, ํธ์ถ ๊ฐ๋ฅํฉ๋๋ค. ํจ์ ํ์ ์ ํฌํจ ๊ด๊ณ๋ ๋ค์ ๋ณต์กํ๋ฐ, ๋ฐํํ์๋ ๊ณต๋ณ์ ์ด๊ณ ์ธ์ํ์๋ ๋ฐ๋ณ์ (contravariant)์ ๋๋ค.
๋ฐํํ์ ๊ณต๋ณ์
๋ ํจ์์ ์ธ์๋ฅผ ๊ณ ๋ คํ์ง ์์ ๋, ๋ฐํํ์ ํฌํจ ๊ด๊ณ์ ๋ฐฉํฅ์ด ๊ณง ์ ์ฒด ํจ์ ํ์ ์ ํฌํจ ๊ด๊ณ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
์ ํจ์ ํ์ ์ ๋ฐํํ์ ๊ณต๋ณ์ ์ผ๊น์? ๋ฐ๋ก ๋ฐํ๊ฐ์ด rvalue๋ก ์ฐ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. ์์์ ํน์ ํ์ ์ lvalue์๋ ๊ทธ ์๋ธํ์ ์ rvalue๋ฅผ ๋ฃ์ ์ ์๋ค๊ณ ํ์ต๋๋ค. ๊ณต๋ณ์ ์ด๋ผ๋ฉด ๋ ์์ ํ์ ์ ํจ์๋ฅผ ํฐ ํ์ ์ ๋์ ํ๋๋ผ๋ ์ฌ์ฉํ ๋ ์ผ๊ด์ฑ์ ์ ์งํ ์ ์์ต๋๋ค.
const fa: () => A = ...
const fb: () => B = ...
let a: A
let f: () => A
// () => A โณ () => B๋ผ๋ฉด, fb๋ฅผ f์ ๋์
ํ ์ ์๊ณ
// f์ ๋ฐํ๊ฐ์ ์์์ ํ๋ ๋๋ก a์ ๋์
ํ ์ ์์ด์ผ ํ๋ค.
f = fb
a = f()
์ธ์ํ์ ๋ฐ๋ณ์
๋ ํจ์์ ๋ฐํํ์ ๊ณ ๋ คํ์ง ์์ ๋, ์ธ์ํ์ ํฌํจ ๊ด๊ณ์ ์ญ์ ์ด ์ ์ฒด ํจ์ ํ์ ์ ํฌํจ ๊ด๊ณ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค. ์ด ์ฑ์ง์ ๋ฐ๋ณ์ฑ(contravariance)์ด๋ผ๊ณ ํฉ๋๋ค.
์ ํจ์ ํ์ ์ ์ธ์ํ์ ๋ฐ๋ณ์ ์ผ๊น์? ๋ฐ๋ก ์ธ์๊ฐ lvalue๋ก ์ฐ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ด๋ค ํจ์๊ฐ ๋ ์์ ํ์ ์ ํจ์๋ก ์นํ์ด ๋๋๋ผ๋, ์ธ์๋ฅผ ๋ฐ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์์ด์ผ ํ๋๋ฐ ๋ฐ๋ณ์ฑ์ ์ด๋ฅผ ๋ณด์ฅํด ์ค๋๋ค.
const fa: (a: A) => void
const fb: (b: B) => void
let f: (b: B) => void
// b๋ A์ ์๋ธํ์
์ธ B ํ์
์ด๋ฏ๋ก, A์ ๋์
์ด ๊ฐ๋ฅ
f = fa
f(b)
ํํธ ํจ์ ์ธ์์ ๊ธธ์ด๋ ๊ณ ๋ ค๋ฅผ ํด์ผ ํ๋๋ฐ์. ์ด๊ฒ ์ญ์ ์ง๊ด๊ณผ ๋ฐ๋๋ก ๋์๊ฐ๋๋ค.
์ธ์๊ฐ ์ ์ ํจ์ ํ์ ์ธ์๊ฐ ๋ง์ ํจ์ ํ์
์ ๊ทธ๋ด๊น์? ์ธ์๊ฐ ์ ์ ํจ์๋ ๋ ๋ง์ ์ธ์๋ฅผ ๋ฐ๋๋ผ๋ ๋ฌธ์ ๊ฐ ์๋๋ ๋ฐ๋ฉด, ์ธ์๋ฅผ ๋ง์ด ์๊ตฌํ๋ ํจ์๊ฐ ๋ ์ ๊ฒ ๋ฐ์ผ๋ฉด ์ ๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
function consume1Arg(x: X): void
function consume2Arg(x: X, y: Y): void
let wide: (x: X, y: Y) => void
wide = consume1Arg
wide(x, y) // consume1Arg๋ y๋ฅผ ๋ฌด์ํจ
let narrow: (x: X) => void
narrow = consume2Arg
// Target signature provides too few arguments. Expected 2 or more, but got 1
narrow(x) // consume2Arg์ y๊ฐ ๊ฒฐ์ ๋์ง ๋ชปํจ
ํน์ ํ์
ํน์ ํ์
์ด๋ JS์์ ๊ฐ์ผ๋ก ์กด์ฌํ์ง ์๊ณ TS์์๋ง ์กด์ฌํ๋ ํ์
์ธ never
, unknown
, any
, void
๋ฅผ ์ด๋ฆ
๋๋ค.
never
, unknown
์ฐ๋ฆฌ๋ ๊ฐ์ ์์ ํ ๋์
์ ํ์
์ ๋์ ๊ด๊ณ๋ก์ ๋ค๋ฃจ๊ธฐ๋ก ํ์ต๋๋ค. ์ด ๊ด์ ์์ never
์ unknown
์ ์์ฃผ ๊ฐ๋จํฉ๋๋ค.
๋ชจ๋ ํ์
T์ ๋ํ์ฌ, never
๋ T์ ์๋ธํ์
์ด๋ฉฐ, T๋ unknown
์ ์๋ธํ์
์
๋๋ค.
never
๋ ์กด์ฌํ ์ ์๋ ๊ฐ์ฅ ์ข์ ํ์
์ผ๋ก, ๊ทธ ์ด๋ค ๊ฐ๋ ๋์
ํ ์ ์์ต๋๋ค. ์ฌ์ง์ด undefined
๋์. never
๋ ์ผ๋ฐ์ ์ธ ์ํฉ์์ ๊ฑฐ์ ์ฐ์ด์ง ์์ง๋ง, ๋ณต์กํ ์ ๋ค๋ฆญ์ ๊ตฌ์ฑ ์ ์๋ชป๋ ๋์
์ ๋ํ ์ง๋ฒ์ ์ค๋ฅ๋ฅผ ๋ฐ์์ํฌ ๋ ์ ์ฉํฉ๋๋ค.
ํํธ unknown
์ ์กด์ฌํ ์ ์๋ ๊ฐ์ฅ ๋์ ํ์
์ผ๋ก, ๊ทธ ์ด๋ค ๊ฐ๋ ๋์
ํ ์ ์์ต๋๋ค. ์ฌ์ง์ด never
ํ์
์ผ๋ก ๊ฐ์ ๋ก ํ๋ณํํ ๊ฐ๋์.
const thisIsNever: never = undefined
// Type 'undefined' is not assignable to type 'never'.
const thisIsUnknown: unknown = 0
// OK
const neverCantReceiveAnything: never = {} as unknown
// Type 'unknown' is not assignable to type 'never'.
const unknownCanReceiveAnything: unknown = {} as never
// OK
const unknownCantBeAssigned: number = 0 as unknown
// Type 'unknown' is not assignable to type 'number'.
any
๊ทธ๋ ๋ค๋ฉด any
๋ ๋ฌด์์ผ๊น์?
never
๋ฅผ ์ ์ธํ ๋ชจ๋ ํ์
T์ ๋ํ์ฌ, any
๋ T์ ์๋ก ์๋ธํ์
๊ด๊ณ์
๋๋ค.
์๋ก ์๋ธํ์
๊ด๊ณ์ด๊ธฐ ๋๋ฌธ์ any
๋ฅผ number
์ ๋์
ํ ์๋ ์๊ณ , number
๋ฅผ any
์ ๋์
ํ ์๋ ์์ต๋๋ค. ๋จ, never
์ any
๋ฅผ ๋์
ํ ์๋ ์์ต๋๋ค.
void
void
๋ ํจ์์ ๋ฐํํ์ ์์ ํ ๋ ์ ์๋ฏธํ ํ์
์ผ๋ก, undefined
์ ์ํผํ์
์
๋๋ค. undefined
๊ณผ ํน์ ํ์
์ ์ ์ธํ ๋ชจ๋ ํ์
๊ณผ๋ ๋ฌด๊ด๊ณ์
๋๋ค.
์ฆ, undefined
๋ฅผ void
์๋ ๋์
ํ ์ ์์ง๋ง ๊ทธ ์ญ์ ์ ๋ฉ๋๋ค. ์ด๋ ํจ์๋ฅผ ์ ์ํ ๋๋ฅผ ์๊ฐํ๋ฉด ํฉ๋ฆฌ์ ์ธ๋ฐ์, void
ํ ํจ์์ return
๋ฌธ์ ์ฌ์ค์ return undefined
์ ๋์ผํ๊ธฐ ๋๋ฌธ์
๋๋ค. ํ์ง๋ง ์ด ํจ์์ ๋ฐํ๊ฐ์ด ์ฌ์ฉ๋์ง ์์์ผ ํ๋ฏ๋ก, ๋ค๋ฅธ ํ์
์ ๋์
์ ๋ถ๊ฐ๋ฅํฉ๋๋ค.
function f(): void {
return undefined // OK
}
const x: number = f()
// Type 'void' is not assignable to type 'number'.
const y: undefined = f()
// Type 'void' is not assignable to type 'undefined'.
ํด์ฆ
๋ค์ ์ค ์ด๋ก ์ ๊ฐ์ฅ ๋์ ํจ์์ ํ์ ์?
(...args: unknown[]) => unknown
(...args: never[]) => unknown
(...args: any[]) => any
(...args: void[]) => never
์ ๋ต ๋ฐ ํ์ด
์ ๋ต์ 2๋ฒ์ ๋๋ค.
- ํจ์์ ํ์
์ค ๊ฐ์ฅ ๋์ ํ์
์ ์ฐพ์์ผ ํ๋ฏ๋ก, ์ฐ์ ๋ฐํํ์ด ์ข์
never
(4๋ฒ)์ ์์์ ๋๋ค. - ์ธ์ ๊ฐ์๋ ๋ชจ๋ ๋ฌดํํ๊ฒ ๊ฐ๊ณ , ์ธ์ํ ์ค ๊ฐ์ฅ ์ข์ ํ์ ์ ์ฐพ์์ผ ํฉ๋๋ค.
- ๋ฐฐ์ด์ ๊ฐ๋ณ ์์ ํ์ ์ ๊ณต๋ณ์ ์ด๋ฏ๋ก, ๊ฐ๋ณ ์์ ์ค ๊ฐ์ฅ ์ข์ ํ์ ์ ์ฐพ์์ผ ํฉ๋๋ค.
- ๋ฐ๋ผ์ ๊ฐ์ฅ ์ข์
never
๋ฅผ ๊ฐ์ง 2๋ฒ์ด ์ ๋ต์ ๋๋ค.
์ค์ ๋ก ์ด ํ์ ์ ํจ์ ํ์ ์ ์์๋ก์ TS ๊ณต์ ๋ฌธ์์ ์ข ์ข ๋ฑ์ฅํ๊ณค ํฉ๋๋ค.
๋ง์น๋ฉฐ
TS์ ๊ถ๊ทน์ ์ธ ๋ชฉํ๋ ์์ ํ ๋์ ๊ณผ ์ฐธ์กฐ๋ฅผ ์คํํ๋ ๊ฒ์ ๋๋ค. ์ด๋ฅผ ์ํด์ ํ์ ๊ณผ ๊ทธ ๋์ ๊ด๊ณ๋ฅผ ์ ์ํ๊ณ , ์์ ํ ๋์ ์ด ๋ฌด์์ธ์ง ์ดํด๋ณด์์ต๋๋ค. ๋ค์ ๊ธ์์๋ TS๊ฐ ์ด๋ป๊ฒ ์์ ํ์ง ์์ ๋์ ์ด๋ ์ฐธ์กฐ๋ฅผ ์ก์๋ด๋์ง ์์๋ณด๊ฒ ์ต๋๋ค.
infer, never๋ง ๋ณด๋ฉด ๋๋ ค์์ง๋ ๋น์ ์ ์ํ ํ์ ์ถ๋ก ์๋ฆฌ์ฆ