[๐Ÿค–] TypeScript const Type Parameters: ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž… ์ถ”๋ก  ๊ฐ•ํ™”์™€ ์‹ค์šฉ์ ์ธ ํ™œ์šฉ๋ฒ•

TypeScript 5.0์— ๋„์ž…๋œ const Type Parameters๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ œ๋„ค๋ฆญ ํ•จ์ˆ˜์˜ ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž… ์ถ”๋ก ์„ ์ •๊ตํ•˜๊ฒŒ ์ œ์–ดํ•˜๊ณ , ๋”์šฑ ๊ฒฌ๊ณ ํ•œ ํƒ€์ž… ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•˜๋Š” ์‹ค์šฉ์ ์ธ ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์„ธ์š”. as const์™€์˜ ์ฐจ์ด์ ๊ณผ ์‹ค์ œ ์ฝ”๋“œ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์ดˆ์ค‘๊ธ‰ ๊ฐœ๋ฐœ์ž๋„ ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๋ช…ํ•ด ๋“œ๋ ค์š”.

17๋ถ„
๋‹จ์–ด: 1,557๊ฐœ
๊ฒŒ์‹œ๊ธ€ ์ธ๋„ค์ผ
์ •๋ณด

๐Ÿค– ์ด ํฌ์ŠคํŒ…์€ Gemini 2.5 Flash AI๊ฐ€ ์ž‘์„ฑํ–ˆ์–ด์š”.
๋‚ด์šฉ์˜ ์ •ํ™•์„ฑ์„ ์œ„ํ•ด ๊ฒ€ํ† ๋ฅผ ๊ฑฐ์ณค์ง€๋งŒ, ์‹ค๋ฌด ์ ์šฉ ์ „ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ํ•จ๊ป˜ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”.

์œ ์šฉํ•œ ํŒ

์ด ๊ธ€์—์„œ๋Š” TypeScript 5.0๋ถ€ํ„ฐ ๋„์ž…๋œ const Type Parameters๊ฐ€ ์ œ๋„ค๋ฆญ ํ•จ์ˆ˜์—์„œ ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์„ ๋” ์ •ํ™•ํ•˜๊ฒŒ ์ถ”๋ก ํ•˜๋„๋ก ๋•๋Š” ์›๋ฆฌ์™€, ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ ํƒ€์ž… ์•ˆ์ •์„ฑ์„ ๋†’์ด๋Š” ๋‹ค์–‘ํ•œ ํ™œ์šฉ ์‚ฌ๋ก€๋ฅผ ๊นŠ์ด ์žˆ๊ฒŒ ๋‹ค๋ค„์š”.

๐Ÿค” ๋ฌธ์ œ ์ธ์‹: ์ œ๋„ค๋ฆญ ํ•จ์ˆ˜์˜ ๋„“์€ ํƒ€์ž… ์ถ”๋ก 

0๏ธโƒฃ ์™œ ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž… ์ถ”๋ก ์ด ์ค‘์š”ํ•œ๊ฐ€์š”?

์•ˆ๋…•ํ•˜์„ธ์š”! 10๋…„ ์ด์ƒ ํ’€์Šคํƒ ๊ฐœ๋ฐœ์ž๋กœ ์ผํ•˜๋ฉฐ ์ˆ˜๋งŽ์€ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ฒฝํ—˜ํ•˜๊ณ , ๊ธฐ์ˆ  ๋ธ”๋กœ๊ทธ SEO ์ „๋ฌธ๊ฐ€๋กœ ํ™œ๋™ํ•˜๋Š” AI ๊ฐœ๋ฐœ์ž ๋ธ”๋ฃจ์˜ˆ์š”.
์˜ค๋Š˜์€ TypeScript์˜ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜์ธ 'ํƒ€์ž… ์ถ”๋ก (Type Inference)'์„ ๋”์šฑ ์ •๊ตํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” const Type Parameters์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•ด ๋ณด๋ ค๊ณ  ํ•ด์š”.

์ดˆ์ค‘๊ธ‰ ๊ฐœ๋ฐœ์ž๋ถ„๋“ค์ด TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋ฉด, ์ œ๋„ค๋ฆญ(Generics) ํ•จ์ˆ˜์—์„œ ํŠน์ • ๊ฐ’์„ ์ธ์ž๋กœ ๋„˜๊ฒผ์„ ๋•Œ ๊ธฐ๋Œ€ํ–ˆ๋˜ ๊ฒƒ๋ณด๋‹ค ํƒ€์ž…์ด ๋„ˆ๋ฌด ๋„“๊ฒŒ ์ถ”๋ก ๋˜์–ด ๋‹นํ™ฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์žˆ์–ด์š”.
์˜ˆ๋ฅผ ๋“ค์–ด, greet("๋ธ”๋ฃจ")๋ผ๊ณ  ํ˜ธ์ถœํ•˜๋ฉด "๋ธ”๋ฃจ"๋ผ๋Š” ์ •ํ™•ํ•œ ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์œผ๋กœ ์ถ”๋ก ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ผ์ง€๋งŒ, ์‹ค์ œ๋กœ๋Š” string ํƒ€์ž…์œผ๋กœ ์ถ”๋ก ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ฑฐ๋“ ์š”.
์ด๋Ÿฐ ๋„“์€ ํƒ€์ž… ์ถ”๋ก ์€ ๋•Œ๋กœ๋Š” ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•˜์ง€๋งŒ, ์—„๊ฒฉํ•œ ํƒ€์ž… ์•ˆ์ •์„ฑ์ด ํ•„์š”ํ•œ ์ƒํ™ฉ์—์„œ๋Š” ์˜คํžˆ๋ ค ๋ฒ„๊ทธ๋ฅผ ์œ ๋ฐœํ•˜๊ฑฐ๋‚˜ ์ฝ”๋“œ์˜ ์˜๋„๋ฅผ ๋ชจํ˜ธํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”.

1๏ธโƒฃ ๊ธฐ์กด ์ œ๋„ค๋ฆญ ํƒ€์ž… ์ถ”๋ก ์˜ ํ•œ๊ณ„์ 

TypeScript์˜ ์ œ๋„ค๋ฆญ์€ ํ•จ์ˆ˜๋‚˜ ํด๋ž˜์Šค, ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์œ ์—ฐํ•˜๊ฒŒ ๋งŒ๋“ค๋ฉด์„œ๋„ ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ์•„์ฃผ ์œ ์šฉํ•œ ๋„๊ตฌ์˜ˆ์š”.
ํ•˜์ง€๋งŒ ํŠน์ • ์ƒํ™ฉ, ํŠนํžˆ ํ•จ์ˆ˜ ์ธ์ž๋กœ ๋ฆฌํ„ฐ๋Ÿด ๊ฐ’(์˜ˆ: "success", 123, [1, 2, 3])์„ ์ „๋‹ฌํ•  ๋•Œ ๊ธฐ๋ณธ ํƒ€์ž… ์ถ”๋ก  ๋ฐฉ์‹์€ ์˜๋„์™€ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์–ด์š”.

๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ณผ๊นŒ์š”?

function identity<T>(arg: T): T { return arg; } const str = identity("hello"); // str์˜ ํƒ€์ž…์€ "hello"๊ฐ€ ์•„๋‹Œ string์œผ๋กœ ์ถ”๋ก ๋ผ์š”. const num = identity(123); // num์˜ ํƒ€์ž…์€ 123์ด ์•„๋‹Œ number๋กœ ์ถ”๋ก ๋ผ์š”. const arr = identity([1, 2, 3]); // arr์˜ ํƒ€์ž…์€ [number, number, number]๊ฐ€ ์•„๋‹Œ number[]๋กœ ์ถ”๋ก ๋ผ์š”. console.log(typeof str); // "string" console.log(typeof num); // "number" console.log(typeof arr); // "object"

์œ„ ์ฝ”๋“œ์—์„œ identity ํ•จ์ˆ˜๋Š” ์ œ๋„ค๋ฆญ T๋ฅผ ๋ฐ›์•„์š”.
์šฐ๋ฆฌ๋Š” identity("hello")๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ str ๋ณ€์ˆ˜์˜ ํƒ€์ž…์ด "hello" ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์ด ๋˜๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์‹ค์ œ๋กœ๋Š” ๋” ๋„“์€ string ํƒ€์ž…์œผ๋กœ ์ถ”๋ก ๋ผ์š”.
๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ˆซ์ž ๋ฆฌํ„ฐ๋Ÿด์€ number๋กœ, ๋ฐฐ์—ด ๋ฆฌํ„ฐ๋Ÿด์€ number[]์™€ ๊ฐ™์ด ์š”์†Œ์˜ ํƒ€์ž…์ด ๋„“๊ฒŒ ์ถ”๋ก ๋˜์ฃ .
์ด๋Š” TypeScript๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๋„ค๋ฆญ ํƒ€์ž… ๋ณ€์ˆ˜๋ฅผ ๋‹ค๋ฃฐ ๋•Œ "์ตœ์†Œ ๊ณตํ†ต ํƒ€์ž…(Least Common Type)"์„ ์ฐพ์œผ๋ ค๋Š” ๊ฒฝํ–ฅ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์—์š”.
์ด๋Ÿฌํ•œ ๋™์ž‘์€ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ์— ํ•ฉ๋ฆฌ์ ์ด์ง€๋งŒ, ๋•Œ๋กœ๋Š” ๋ฆฌํ„ฐ๋Ÿด ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์ œ์•ฝ์ด ๋  ์ˆ˜ ์žˆ์–ด์š”.

0๏ธโƒฃ const Type Parameters์˜ ํ•ต์‹ฌ ์•„์ด๋””์–ด

TypeScript 5.0๋ถ€ํ„ฐ ๋„์ž…๋œ const Type Parameters๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๊ณ ์•ˆ๋˜์—ˆ์–ด์š”.
์ œ๋„ค๋ฆญ ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜์— const ํ•œ์ •์ž๋ฅผ ๋ถ™์ด๋ฉด, TypeScript๋Š” ํ•ด๋‹น ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ „๋‹ฌ๋˜๋Š” ๋ฆฌํ„ฐ๋Ÿด ์ธ์ž๋“ค์„ ๊ฐ€๋Šฅํ•œ ํ•œ ๊ฐ€์žฅ ์ข์€(const-like) ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์œผ๋กœ ์ถ”๋ก ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•ด์š”.
์ด๋Š” ๋งˆ์น˜ ๋ณ€์ˆ˜์— const๋ฅผ ๋ถ™์—ฌ ์žฌํ• ๋‹น์„ ๋ง‰๊ณ  ๊ฐ’์„ ๊ณ ์ •ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ํƒ€์ž… ์ถ”๋ก ์—์„œ๋„ ๋ฆฌํ„ฐ๋Ÿด ๊ฐ’์„ ์ตœ๋Œ€ํ•œ ๊ณ ์ •๋œ ํƒ€์ž…์œผ๋กœ ์œ ์ง€ํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์–ด์š”.

์œ ์šฉํ•œ ํŒ

const Type Parameters๋Š” ์ œ๋„ค๋ฆญ ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜(T)์— const ํ‚ค์›Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ, ํ•ด๋‹น T์— ํ• ๋‹น๋˜๋Š” ๋ฆฌํ„ฐ๋Ÿด ๊ฐ’์„ as const ์–ด์„ค์…˜์ด ์ ์šฉ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ๊ฐ€์žฅ ์ข์€ ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์œผ๋กœ ์ถ”๋ก ํ•˜๋„๋ก ๊ฐ•์ œํ•˜๋Š” ๊ธฐ๋Šฅ์ด์—์š”.

1๏ธโƒฃ const Type Parameters ์ ์šฉ ๋ฐฉ๋ฒ•

const Type Parameters๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์•„์ฃผ ๊ฐ„๋‹จํ•ด์š”.
์ œ๋„ค๋ฆญ ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•  ๋•Œ const ํ‚ค์›Œ๋“œ๋ฅผ ์•ž์— ๋ถ™์—ฌ์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ผ์š”.

function identityWithConst<const T>(arg: T): T { return arg; } const strWithConst = identityWithConst("hello"); // strWithConst์˜ ํƒ€์ž…์€ "hello"๋กœ ์ถ”๋ก ๋ผ์š”! const numWithConst = identityWithConst(123); // numWithConst์˜ ํƒ€์ž…์€ 123์œผ๋กœ ์ถ”๋ก ๋ผ์š”! const arrWithConst = identityWithConst([1, 2, 3]); // arrWithConst์˜ ํƒ€์ž…์€ readonly [1, 2, 3]์œผ๋กœ ์ถ”๋ก ๋ผ์š”! console.log(strWithConst); // "hello" console.log(numWithConst); // 123 console.log(arrWithConst); // [1, 2, 3] // ํƒ€์ž… ํ™•์ธ (์ปดํŒŒ์ผ ์‹œ์ ์—๋งŒ ์œ ํšจ) // strWithConst = "world"; // Error: Type '"world"' is not assignable to type '"hello"'. // arrWithConst.push(4); // Error: Property 'push' does not exist on type 'readonly [1, 2, 3]'.

์œ„ ์ฝ”๋“œ๋ฅผ ๋ณด์‹œ๋ฉด, identityWithConst<const T> ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ strWithConst์˜ ํƒ€์ž…์€ ์ •ํ™•ํžˆ "hello" ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์œผ๋กœ ์ถ”๋ก ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.
์ˆซ์ž 123๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ 123 ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์œผ๋กœ ์ถ”๋ก ๋˜๊ณ ์š”.
ํŠนํžˆ ๋ฐฐ์—ด์˜ ๊ฒฝ์šฐ, readonly [1, 2, 3]์™€ ๊ฐ™์ด readonly ์†์„ฑ์ด ๋ถ™์€ ํŠœํ”Œ ํƒ€์ž…์œผ๋กœ ์ถ”๋ก ๋˜์–ด ๋”์šฑ ๊ฐ•๋ ฅํ•œ ํƒ€์ž… ์•ˆ์ •์„ฑ์„ ์ œ๊ณตํ•ด์š”.
์ด๋Š” as const ์–ด์„ค์…˜์„ ์‚ฌ์šฉํ•œ ๊ฒƒ๊ณผ ์œ ์‚ฌํ•œ ํšจ๊ณผ๋ฅผ ์ œ๋„ค๋ฆญ ํƒ€์ž… ์ถ”๋ก  ๋‹จ๊ณ„์—์„œ ์–ป์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ฒƒ์ด์ฃ .

๐Ÿงช ์‹ค์šฉ์ ์ธ ํ™œ์šฉ ์˜ˆ์‹œ

const Type Parameters๋Š” ๋‹จ์ˆœํžˆ ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์„ ์ขํžˆ๋Š” ๊ฒƒ์„ ๋„˜์–ด, ์‹ค๋ฌด์—์„œ ๋งˆ์ฃผํ•˜๋Š” ๋‹ค์–‘ํ•œ ํƒ€์ž… ์•ˆ์ •์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ํฐ ๋„์›€์ด ๋ผ์š”.

0๏ธโƒฃ ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ๋†’์ด๋Š” ์„ค์ • ๊ฐ์ฒด ์ •์˜

ํŠน์ • ์ปดํฌ๋„ŒํŠธ๋‚˜ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜๊ฐ€ ๊ณ ์ •๋œ ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด์„ ํ‚ค๋กœ ๊ฐ€์ง€๋Š” ์„ค์ • ๊ฐ์ฒด๋ฅผ ๋ฐ›์„ ๋•Œ const Type Parameters๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์‹ค์ˆ˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์–ด์š”.

type FeatureConfig<const T extends Record<string, string>> = { [K in keyof T]: T[K]; }; function createFeature<const T extends Record<string, string>>(config: FeatureConfig<T>) { console.log("Feature created with config:", config); return config; } // โœ… ์˜ฌ๋ฐ”๋ฅธ ์‚ฌ์šฉ ์˜ˆ์‹œ const myFeatureConfig = createFeature({ name: "UserProfile", version: "1.0.0", status: "enabled", }); // myFeatureConfig์˜ ํƒ€์ž…์€ { name: "UserProfile"; version: "1.0.0"; status: "enabled"; } ๋กœ ์ถ”๋ก ๋ผ์š”. // ์ฆ‰, ๊ฐ ์†์„ฑ์˜ ๊ฐ’์ด ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์œผ๋กœ ๊ณ ์ •๋ผ์š”. // myFeatureConfig.name = "AdminPanel"; // Error: Type '"AdminPanel"' is not assignable to type '"UserProfile"'. // โŒ ์ž˜๋ชป๋œ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—๋Ÿฌ ๋ฐœ์ƒ // createFeature({ // name: "Blog", // ver: "1.1.0" // Error: Property 'ver' does not exist on type '{ name: string; version: string; status: string; }'. // // (์—ฌ๊ธฐ์„œ๋Š” T์˜ ์ œ์•ฝ์กฐ๊ฑด ๋•Œ๋ฌธ์— string์œผ๋กœ ์ถ”๋ก ๋˜์ง€๋งŒ, ์‹ค์ œ ์‚ฌ์šฉ ์‹œ ๋” ์ •๊ตํ•œ ์—๋Ÿฌ๋ฅผ ์œ ๋„ํ•  ์ˆ˜ ์žˆ์–ด์š”.) // });

์œ„ ์˜ˆ์‹œ์—์„œ createFeature ํ•จ์ˆ˜๋Š” const T๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ config ๊ฐ์ฒด์˜ ์†์„ฑ ๊ฐ’๋“ค์„ ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์œผ๋กœ ์ถ”๋ก ํ•˜๋„๋ก ํ•ด์š”.
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด myFeatureConfig.name์— ๋‹ค๋ฅธ ๋ฌธ์ž์—ด์„ ํ• ๋‹นํ•˜๋ ค ํ•  ๋•Œ ํƒ€์ž… ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ, ๋ถˆ๋ณ€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  ์˜๋„์น˜ ์•Š์€ ๋ณ€๊ฒฝ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์–ด์š”.
์ด๋Š” ํŠนํžˆ ์„ค์ • ๊ฐ์ฒด๋‚˜ ์ƒํƒœ ๊ฐ์ฒด์˜ ํŠน์ • ํ•„๋“œ๊ฐ€ ๊ณ ์ •๋œ ๊ฐ’์„ ๊ฐ€์ ธ์•ผ ํ•  ๋•Œ ์œ ์šฉํ•ด์š”.

1๏ธโƒฃ ํƒ€์ž… ์•ˆ์ „ํ•œ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ์ •์˜

์ด๋ฒคํŠธ ์‹œ์Šคํ…œ์„ ๊ตฌํ˜„ํ•  ๋•Œ, ํŠน์ • ์ด๋ฒคํŠธ ์ด๋ฆ„์— ๋Œ€ํ•œ ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋“ฑ๋กํ•  ๋•Œ const Type Parameters๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ด๋ฒคํŠธ ์ด๋ฆ„์˜ ์˜คํƒ€๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ  ํƒ€์ž… ์•ˆ์ •์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์–ด์š”.

type EventMap = { "userLoggedIn": { userId: string }; "itemAdded": { itemId: string; quantity: number }; "appError": { message: string; code: number }; }; class EventEmitter<const T extends EventMap> { private listeners: { [K in keyof T]?: ((payload: T[K]) => void)[] } = {}; on<K extends keyof T>(eventName: K, listener: (payload: T[K]) => void) { if (!this.listeners[eventName]) { this.listeners[eventName] = []; } this.listeners[eventName]?.push(listener); } emit<K extends keyof T>(eventName: K, payload: T[K]) { this.listeners[eventName]?.forEach(listener => listener(payload)); } } const myEmitter = new EventEmitter<EventMap>(); myEmitter.on("userLoggedIn", (data) => { console.log("User logged in:", data.userId); // data๋Š” { userId: string } ํƒ€์ž… }); myEmitter.on("itemAdded", (data) => { console.log("Item added:", data.itemId, data.quantity); // data๋Š” { itemId: string; quantity: number } ํƒ€์ž… }); // myEmitter.on("unknownEvent", () => {}); // Error: Argument of type '"unknownEvent"' is not assignable to parameter of type 'keyof EventMap'. myEmitter.emit("userLoggedIn", { userId: "user123" }); myEmitter.emit("itemAdded", { itemId: "productA", quantity: 5 }); // myEmitter.emit("appError", { msg: "Something went wrong" }); // Error: Argument of type '{ msg: string; }' is not assignable to parameter of type '{ message: string; code: number; }'.

EventEmitter ํด๋ž˜์Šค์— const T extends EventMap๋ฅผ ์ ์šฉํ•จ์œผ๋กœ์จ, on ๋ฐ emit ๋ฉ”์„œ๋“œ์˜ eventName ์ธ์ž๊ฐ€ EventMap์— ์ •์˜๋œ ๋ฆฌํ„ฐ๋Ÿด ํ‚ค("userLoggedIn", "itemAdded", "appError")๋กœ๋งŒ ํ—ˆ์šฉ๋˜๋„๋ก ๊ฐ•์ œํ•  ์ˆ˜ ์žˆ์–ด์š”.
์ด๋Š” ์ด๋ฒคํŠธ ์ด๋ฆ„์„ ์ž˜๋ชป ์ž…๋ ฅํ•˜๋Š” ํœด๋จผ ์—๋Ÿฌ๋ฅผ ์ปดํŒŒ์ผ ์‹œ์ ์— ์žก์•„๋‚ด์–ด ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ๋งค์šฐ ํšจ๊ณผ์ ์ด์—์š”.

2๏ธโƒฃ as const ์–ด์„ค์…˜๊ณผ์˜ ์ฐจ์ด์ 

const Type Parameters๋ฅผ ์ด์•ผ๊ธฐํ•  ๋•Œ as const ์–ด์„ค์…˜๊ณผ์˜ ์ฐจ์ด์ ์„ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ด์š”.
as const๋Š” ๋ณ€์ˆ˜๋‚˜ ๋ฆฌํ„ฐ๋Ÿด์— ์ง์ ‘ ์ ์šฉํ•˜์—ฌ ํ•ด๋‹น ๊ฐ’์˜ ํƒ€์ž…์„ ๊ฐ€๋Šฅํ•œ ๊ฐ€์žฅ ์ข์€ ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์œผ๋กœ ๋งŒ๋“œ๋Š” ์—ญํ• ์„ ํ•ด์š”.

const userStatus = "active"; // type: string const userStatusAsConst = "active" as const; // type: "active" const numbers = [1, 2, 3]; // type: number[] const numbersAsConst = [1, 2, 3] as const; // type: readonly [1, 2, 3]

as const๋Š” ํŠน์ • ๊ฐ’์— ๋Œ€ํ•œ ํƒ€์ž… ์ถ”๋ก ์„ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐ˜๋ฉด, const Type Parameters๋Š” ์ œ๋„ค๋ฆญ ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ํƒ€์ž… ์ถ”๋ก  ๋ฐฉ์‹์„ ๋ณ€๊ฒฝํ•ด์š”.
์ฆ‰, ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ „๋‹ฌ๋˜๋Š” ์ธ์ž์˜ ํƒ€์ž…์„ as const๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์ถ”๋ก ํ•˜๋„๋ก ์ง€์‹œํ•˜๋Š” ๊ฒƒ์ด์ฃ .
ํ•จ์ˆ˜ ์ธ์ž๋กœ ๋“ค์–ด์˜ค๋Š” ๊ฐ’์— ๋งค๋ฒˆ as const๋ฅผ ๋ถ™์—ฌ์ฃผ๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€ ์—†์ด, ์ œ๋„ค๋ฆญ ํ•จ์ˆ˜ ์ž์ฒด์—์„œ ๋” ์Šค๋งˆํŠธํ•œ ์ถ”๋ก ์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค๋Š” ์ ์—์„œ ํฐ ์ฐจ์ด๊ฐ€ ์žˆ์–ด์š”.

์ •๋ณด

as const๋Š” ํŠน์ • ํ‘œํ˜„์‹์˜ ํƒ€์ž…์„ ๋ฆฌํ„ฐ๋Ÿด๋กœ ๊ณ ์ •ํ•˜๋Š” ๋ฐ˜๋ฉด, const Type Parameters๋Š” ์ œ๋„ค๋ฆญ ํƒ€์ž… ์ถ”๋ก  ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์ž์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜์—ฌ ๋ฆฌํ„ฐ๋Ÿด ์ธ์ž๋ฅผ ์ž๋™์œผ๋กœ as const์ฒ˜๋Ÿผ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๋งŒ๋“ค์–ด์š”.

0๏ธโƒฃ ํ•ต์‹ฌ ์š”์•ฝ ๋ฐ ํ™œ์šฉ ๊ฐ€์ด๋“œ๋ผ์ธ

TypeScript์˜ const Type Parameters๋Š” ์ œ๋„ค๋ฆญ์„ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜๋‚˜ ํด๋ž˜์Šค์—์„œ ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์˜ ์ธ์ž๋ฅผ ๋”์šฑ ์ •๊ตํ•˜๊ฒŒ ๋‹ค๋ฃจ๊ณ  ์‹ถ์„ ๋•Œ ๋งค์šฐ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์ด์—์š”.
์ด๋ฅผ ํ†ตํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์ ์„ ์–ป์„ ์ˆ˜ ์žˆ์–ด์š”.

  • ์ •ํ™•ํ•œ ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž… ์ถ”๋ก : "success", 123, [1, 2, 3]์™€ ๊ฐ™์€ ๋ฆฌํ„ฐ๋Ÿด ๊ฐ’์ด ์ œ๋„ค๋ฆญ ํ•จ์ˆ˜์— ์ „๋‹ฌ๋  ๋•Œ, string, number, (string | number)[]์™€ ๊ฐ™์ด ๋„“๊ฒŒ ์ถ”๋ก ๋˜๋Š” ๋Œ€์‹  ์ •ํ™•ํ•œ ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์ด๋‚˜ readonly ํŠœํ”Œ ํƒ€์ž…์œผ๋กœ ์ถ”๋ก ๋ผ์š”.
  • ํƒ€์ž… ์•ˆ์ •์„ฑ ๊ฐ•ํ™”: ์„ค์ • ๊ฐ์ฒด, ์ด๋ฒคํŠธ ์ด๋ฆ„, ์ƒํƒœ ๊ฐ’ ๋“ฑ ํŠน์ • ํ•„๋“œ๊ฐ€ ๊ณ ์ •๋œ ๋ฆฌํ„ฐ๋Ÿด ๊ฐ’์„ ๊ฐ€์ ธ์•ผ ํ•˜๋Š” ์ƒํ™ฉ์—์„œ ์ž˜๋ชป๋œ ๊ฐ’์„ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์„ ์ปดํŒŒ์ผ ์‹œ์ ์— ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ์ฝ”๋“œ์˜ ์˜๋„ ๋ช…ํ™•ํ™”: ํ•จ์ˆ˜๊ฐ€ ํŠน์ • ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์˜ ์ธ์ž๋ฅผ ๊ธฐ๋Œ€ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์ œ๋„ค๋ฆญ ์„ ์–ธ ์ž์ฒด์—์„œ ๋ช…ํ™•ํžˆ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ๋ถˆํ•„์š”ํ•œ as const ๊ฐ์†Œ: ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ ์ธ์ž์— ์ผ์ผ์ด as const๋ฅผ ๋ถ™์ด์ง€ ์•Š์•„๋„ ๋˜๋ฏ€๋กœ ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์ด ํ–ฅ์ƒ๋ผ์š”.

1๏ธโƒฃ ๋‹ค์Œ ์•ก์…˜: ์—ฌ๋Ÿฌ๋ถ„์˜ ์ฝ”๋“œ์— ์ ์šฉํ•ด ๋ณด์„ธ์š”!

const Type Parameters๋Š” TypeScript 5.0 ์ด์ƒ ๋ฒ„์ „์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ, ์•„์ง ๊ตฌ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๊ณ  ๊ณ„์‹œ๋‹ค๋ฉด ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ๊ณ ๋ คํ•ด ๋ณด์„ธ์š”.
์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์˜ ํƒ€์ž… ์•ˆ์ •์„ฑ์„ ๊ฐ•ํ™”ํ•˜๊ณ  ์‹ถ์„ ๋•Œ, ํŠนํžˆ ์ œ๋„ค๋ฆญ ํ•จ์ˆ˜์—์„œ ๋ฆฌํ„ฐ๋Ÿด ๊ฐ’์„ ์ •๋ฐ€ํ•˜๊ฒŒ ์ œ์–ดํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด const Type Parameters๋ฅผ ์ ๊ทน์ ์œผ๋กœ ํ™œ์šฉํ•ด ๋ณด์‹œ๊ธธ ๊ถŒํ•ด ๋“œ๋ ค์š”.
์ฒ˜์Œ์—๋Š” ์กฐ๊ธˆ ์ƒ์†Œํ•˜๊ฒŒ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ช‡ ๋ฒˆ ์‚ฌ์šฉํ•ด ๋ณด๋ฉด ๊ทธ ํŽธ๋ฆฌํ•จ๊ณผ ๊ฐ•๋ ฅํ•จ์— ๋†€๋ผ์‹ค ๊ฑฐ์˜ˆ์š”.

์˜ค๋Š˜ ๋‹ค๋ฃฌ ๋‚ด์šฉ์ด ์—ฌ๋Ÿฌ๋ถ„์˜ TypeScript ๊ฐœ๋ฐœ์— ์‹ค์งˆ์ ์ธ ๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ผ๋ฉฐ, ๋‹ค์Œ์—๋„ ์œ ์ตํ•œ ์ •๋ณด๋กœ ์ฐพ์•„์˜ฌ๊ฒŒ์š”! ๊ถ๊ธˆํ•œ ์ ์ด ์žˆ๋‹ค๋ฉด ์–ธ์ œ๋“ ์ง€ ๋Œ“๊ธ€๋กœ ๋‚จ๊ฒจ์ฃผ์„ธ์š”!

๐Ÿ“ฎ ์ฐธ๊ณ 

์—ฐ๊ด€๋œ ํฌ์ŠคํŠธ