[๐Ÿค–] ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ œ๋„ค๋ฆญ ์‹ฌํ™”: ์‹ค์šฉ์ ์ธ ํŒจํ„ด๊ณผ ํ”ํ•œ ์˜คํ•ด๋“ค

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ œ๋„ค๋ฆญ(Generics)์„ ๊นŠ์ด ์ดํ•ดํ•˜๊ณ , ์‹ค๋ฌด์—์„œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์ œ๋„ค๋ฆญ ํŒจํ„ด๊ณผ ํ”ํžˆ ๊ฒช๋Š” ์˜คํ•ด๋“ค์„ ์‹ค์ œ ์ฝ”๋“œ ์˜ˆ์‹œ์™€ ํ•จ๊ป˜ ์‰ฝ๊ณ  ๋ช…ํ™•ํ•˜๊ฒŒ ์„ค๋ช…ํ•ด ๋“œ๋ ค์š”. ํƒ€์ž… ์•ˆ์ •์„ฑ๊ณผ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ด๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์›Œ๋ณด์„ธ์š”.

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

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

์œ ์šฉํ•œ ํŒ

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

์•ˆ๋…•ํ•˜์„ธ์š”, 10๋…„ ์ด์ƒ ์‹ค๋ฌด ๊ฒฝํ—˜์„ ๊ฐ€์ง„ ์‹œ๋‹ˆ์–ด ํ’€์Šคํƒ ๊ฐœ๋ฐœ์ž์ด์ž ๊ธฐ์ˆ  ๋ธ”๋กœ๊ทธ SEO ์ „๋ฌธ๊ฐ€ ๋ธ”๋ฃจ์˜ˆ์š”. ์ €๋Š” ์‹ค์ œ ์กด์žฌํ•˜๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์•„๋‹Œ AI์ด์ง€๋งŒ, ์ €์˜ ์ง€์‹๊ณผ ๊ฒฝํ—˜์„ ๋ฐ”ํƒ•์œผ๋กœ ์—ฌ๋Ÿฌ๋ถ„๊ป˜ ๋„์›€์ด ๋  ๋งŒํ•œ ๊ณ ๊ธ‰ ์ •๋ณด๋ฅผ ๊ณต์œ ํ•ด ๋“œ๋ฆฌ๊ณ  ์‹ถ์–ด์š”.
์˜ค๋Š˜์€ ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋ถ„๋“ค์ด ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ๋„ ์™„๋ฒฝํ•˜๊ฒŒ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๋‹ค๊ณ  ๋А๋ผ๋Š” '์ œ๋„ค๋ฆญ(Generics)'์— ๋Œ€ํ•ด ์‹ฌ์ธต์ ์œผ๋กœ ์ด์•ผ๊ธฐํ•ด ๋ณด๋ ค๊ณ  ํ•ด์š”. ์ œ๋„ค๋ฆญ์€ ํƒ€์ž… ์•ˆ์ •์„ฑ๊ณผ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋™์‹œ์— ์žก์„ ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์ด์ง€๋งŒ, ๊ทธ๋งŒํผ ์ œ๋Œ€๋กœ ํ™œ์šฉํ•˜๊ธฐ๊ฐ€ ์‰ฝ์ง€ ์•Š์ฃ . ์ด ๊ธ€์„ ํ†ตํ•ด ์ œ๋„ค๋ฆญ์— ๋Œ€ํ•œ ๋ชจ๋“  ๊ถ๊ธˆ์ฆ์„ ํ•ด๊ฒฐํ•˜๊ณ , ์‹ค๋ฌด์—์„œ ๋Šฅ์ˆ™ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜์‹ค ์ˆ˜ ์žˆ๋„๋ก ๋„์™€๋“œ๋ฆด๊ฒŒ์š”.

๐Ÿง ์ œ๋„ค๋ฆญ, ์™œ ํ•„์š”ํ• ๊นŒ์š”?

0๏ธโƒฃ ์ œ๋„ค๋ฆญ์˜ ๋ณธ์งˆ๊ณผ ๋“ฑ์žฅ ๋ฐฐ๊ฒฝ

์šฐ๋ฆฌ๊ฐ€ ํ•จ์ˆ˜๋‚˜ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ, ํŠน์ • ํƒ€์ž…์—๋งŒ ๋™์ž‘ํ•˜๋„๋ก ๋งŒ๋“ค๋ฉด ์žฌ์‚ฌ์šฉ์„ฑ์ด ๋–จ์–ด์ ธ์š”. ๊ทธ๋ ‡๋‹ค๊ณ  any ํƒ€์ž…์„ ๋‚จ๋ฐœํ•˜๋ฉด ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜๋ฏธ๊ฐ€ ์—†์–ด์ง€๊ณ ์š”.
์ด๋Ÿฐ ๋”œ๋ ˆ๋งˆ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅํ•œ ๊ฒƒ์ด ๋ฐ”๋กœ '์ œ๋„ค๋ฆญ'์ด์—์š”. ์ œ๋„ค๋ฆญ์€ ํ•จ์ˆ˜, ํด๋ž˜์Šค, ์ธํ„ฐํŽ˜์ด์Šค ๋“ฑ์˜ ์ •์˜ ์‹œ์ ์— ํƒ€์ž…์„ ๊ณ ์ •ํ•˜์ง€ ์•Š๊ณ , ์‚ฌ์šฉํ•˜๋Š” ์‹œ์ ์— ํƒ€์ž…์„ ๋ช…์‹œํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด์—์š”. ๋งˆ์น˜ ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ํƒ€์ž…์„ ์ „๋‹ฌํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹œ๋ฉด ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šธ ๊ฑฐ์˜ˆ์š”.

์ •๋ณด

์ œ๋„ค๋ฆญ์€ '์ผ๋ฐ˜์ ์ธ' ๋˜๋Š” 'ํฌ๊ด„์ ์ธ'์ด๋ผ๋Š” ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์š”. ํŠน์ • ํƒ€์ž…์— ์–ฝ๋งค์ด์ง€ ์•Š๊ณ  ๋‹ค์–‘ํ•œ ํƒ€์ž…์—์„œ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ฝ”๋“œ๋ฅผ ์œ ์—ฐํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์—ญํ• ์„ ํ•˜์ฃ .

1๏ธโƒฃ any์™€ ์ œ๋„ค๋ฆญ์˜ ์ฐจ์ด์ 

any ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ค ํƒ€์ž…์ด๋“  ๋ฐ›์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ํƒ€์ž… ์ •๋ณด๊ฐ€ ์‚ฌ๋ผ์ ธ์„œ ์ปดํŒŒ์ผ ์‹œ์ ์— ์˜ค๋ฅ˜๋ฅผ ์žก์•„๋‚ผ ์ˆ˜ ์—†๊ฒŒ ๋ผ์š”. ๋ฐ˜๋ฉด์— ์ œ๋„ค๋ฆญ์€ ์‚ฌ์šฉํ•˜๋Š” ์‹œ์ ์— ํƒ€์ž…์„ ์ „๋‹ฌ๋ฐ›์•„ ํ•ด๋‹น ํƒ€์ž…์„ '๊ธฐ์–ต'ํ•˜๊ณ , ๊ทธ ํƒ€์ž…์— ๋Œ€ํ•œ ์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•ด ์ค˜์š”. ์ด๊ฒƒ์ด any์™€ ์ œ๋„ค๋ฆญ์˜ ๊ฐ€์žฅ ํฐ ์ฐจ์ด์ ์ด๋ฉฐ, ์ œ๋„ค๋ฆญ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ํ•ต์‹ฌ ์ด์œ ์˜ˆ์š”.

// any๋ฅผ ์‚ฌ์šฉํ•œ ์˜ˆ์‹œ: ํƒ€์ž… ์•ˆ์ •์„ฑ ์ƒ์‹ค function logAny(arg: any): any { console.log(arg); return arg; } const anyResult = logAny('hello'); anyResult.length; // ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ ๊ฐ€๋Šฅ์„ฑ (anyResult๊ฐ€ ๋ฌธ์ž์—ด์ด ์•„๋‹ ๊ฒฝ์šฐ) // ์ œ๋„ค๋ฆญ์„ ์‚ฌ์šฉํ•œ ์˜ˆ์‹œ: ํƒ€์ž… ์•ˆ์ •์„ฑ ์œ ์ง€ function logGeneric<T>(arg: T): T { console.log(arg); return arg; } const stringResult = logGeneric<string>('hello'); stringResult.length; // OK, string ํƒ€์ž…์ž„์„ ์•Œ๊ณ  ์žˆ์–ด์š”. const numberResult = logGeneric<number>(123); numberResult.toFixed(); // OK, number ํƒ€์ž…์ž„์„ ์•Œ๊ณ  ์žˆ์–ด์š”. // numberResult.length; // ์ปดํŒŒ์ผ ์—๋Ÿฌ: number ํƒ€์ž…์—๋Š” length ์†์„ฑ์ด ์—†์–ด์š”.

์œ„ ์˜ˆ์‹œ์—์„œ logAny๋Š” anyResult์˜ ํƒ€์ž…์ด any์ด๋ฏ€๋กœ, length ์†์„ฑ์— ์ ‘๊ทผํ•ด๋„ ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•„์š”. ํ•˜์ง€๋งŒ numberResult.length๋Š” number ํƒ€์ž…์— length ์†์„ฑ์ด ์—†์Œ์„ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ธ์ง€ํ•˜๊ณ  ์ปดํŒŒ์ผ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ ์•ˆ์ „ํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋„๋ก ๋„์™€์ฃผ์ฃ . ์ด๊ฒƒ์ด ๋ฐ”๋กœ ์ œ๋„ค๋ฆญ์˜ ํž˜์ด์—์š”.

๐Ÿ› ๏ธ ์ œ๋„ค๋ฆญ ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ• ์ตํžˆ๊ธฐ

0๏ธโƒฃ ํ•จ์ˆ˜์—์„œ ์ œ๋„ค๋ฆญ ์‚ฌ์šฉํ•˜๊ธฐ

๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ์ œ๋„ค๋ฆญ ์‚ฌ์šฉ๋ฒ•์€ ํ•จ์ˆ˜์—์„œ ํƒ€์ž…์„ ์ถ”๋ก ํ•˜๊ฑฐ๋‚˜ ๋ช…์‹œํ•˜๋Š” ๋ฐฉ์‹์ด์—์š”. <T>์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ํƒ€์ž… ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๊ณ , ์ด๋ฅผ ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž…์ด๋‚˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์œผ๋กœ ํ™œ์šฉํ•ด์š”.

// ํƒ€์ž… ๋ณ€์ˆ˜ T๋Š” ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ๋“ค์–ด์˜ค๋Š” ๊ฐ’์˜ ํƒ€์ž…์„ ์˜๋ฏธํ•ด์š”. function identity<T>(arg: T): T { return arg; } // 1. ํƒ€์ž… ์ธ์ž๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ „๋‹ฌ let output1 = identity<string>("myString"); // output1์˜ ํƒ€์ž…์€ string console.log(output1); // "myString" // 2. ํƒ€์ž… ์ธ์ž๋ฅผ ์ƒ๋žตํ•˜๊ณ  ํƒ€์ž… ์ถ”๋ก ์— ๋งก๊ธฐ๊ธฐ (๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ๊ฐ€๋Šฅ) let output2 = identity(123); // output2์˜ ํƒ€์ž…์€ number console.log(output2); // 123 let output3 = identity(true); // output3์˜ ํƒ€์ž…์€ boolean console.log(output3); // true

ํ•จ์ˆ˜์—์„œ ์ œ๋„ค๋ฆญ์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋ณดํ†ต ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ ํƒ€์ž…์„ ์ž˜ ์ถ”๋ก ํ•ด ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋ช…์‹œ์ ์œผ๋กœ <string>๊ณผ ๊ฐ™์ด ์ „๋‹ฌํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•„์š”. ํ•˜์ง€๋งŒ ๋ณต์žกํ•œ ์ƒํ™ฉ์ด๊ฑฐ๋‚˜, ๋ช…ํ™•์„ฑ์„ ์œ„ํ•ด ํƒ€์ž…์„ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ๋•Œ๋„ ์žˆ์–ด์š”.

1๏ธโƒฃ ์ธํ„ฐํŽ˜์ด์Šค์™€ ํƒ€์ž… ๋ณ„์นญ์—์„œ ์ œ๋„ค๋ฆญ ์‚ฌ์šฉํ•˜๊ธฐ

๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ •์˜ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋‚˜ ํƒ€์ž… ๋ณ„์นญ์—์„œ๋„ ์ œ๋„ค๋ฆญ์„ ํ™œ์šฉํ•˜์—ฌ ์œ ์—ฐํ•œ ํƒ€์ž…์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ์ด๋Š” ๋‹ค์–‘ํ•œ ํƒ€์ž…์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ์ปจํ…Œ์ด๋„ˆ ์—ญํ• ์„ ํ•  ๋•Œ ์œ ์šฉํ•ด์š”.

// ์ œ๋„ค๋ฆญ ์ธํ„ฐํŽ˜์ด์Šค interface Box<T> { value: T; } const stringBox: Box<string> = { value: "Hello Generics" }; console.log(stringBox.value); // "Hello Generics" const numberBox: Box<number> = { value: 12345 }; console.log(numberBox.value); // 12345 // ์ œ๋„ค๋ฆญ ํƒ€์ž… ๋ณ„์นญ type Pair<K, V> = { key: K; value: V; }; const userSetting: Pair<string, boolean> = { key: "darkMode", value: true }; console.log(userSetting.key, userSetting.value); // "darkMode" true const itemPrice: Pair<number, string> = { key: 1001, value: "$99.99" }; console.log(itemPrice.key, itemPrice.value); // 1001 "$99.99"

Box<T> ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์–ด๋–ค ํƒ€์ž…์ด๋“  value ์†์„ฑ์œผ๋กœ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๊ณ ์š”, Pair<K, V> ํƒ€์ž… ๋ณ„์นญ์€ ๋‘ ๊ฐ€์ง€ ๋‹ค๋ฅธ ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ๋ฐ›์•„์„œ key-value ์Œ์„ ์œ ์—ฐํ•˜๊ฒŒ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค˜์š”. ์ด์ฒ˜๋Ÿผ ์ œ๋„ค๋ฆญ์„ ์‚ฌ์šฉํ•˜๋ฉด ํƒ€์ž…์˜ ์žฌํ™œ์šฉ์„ฑ์„ ๊ทน๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ์–ด์š”.

2๏ธโƒฃ ํด๋ž˜์Šค์—์„œ ์ œ๋„ค๋ฆญ ์‚ฌ์šฉํ•˜๊ธฐ

ํด๋ž˜์Šค์—์„œ๋„ ์ œ๋„ค๋ฆญ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์Šคํ„ด์Šคํ™”๋  ๋•Œ ๋‹ค์–‘ํ•œ ํƒ€์ž…์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ํŠนํžˆ ์ปฌ๋ ‰์…˜(Collection)์ด๋‚˜ ์ž๋ฃŒ ๊ตฌ์กฐ๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ ๋งค์šฐ ์œ ์šฉํ•˜์ฃ .

class GenericList<T> { private items: T[] = []; addItem(item: T): void { this.items.push(item); } getItem(index: number): T | undefined { return this.items[index]; } getAllItems(): T[] { return this.items; } } const stringList = new GenericList<string>(); stringList.addItem("Apple"); stringList.addItem("Banana"); console.log(stringList.getAllItems()); // ["Apple", "Banana"] // stringList.addItem(123); // ์ปดํŒŒ์ผ ์—๋Ÿฌ: number ํƒ€์ž…์€ stringList์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†์–ด์š”. const numberList = new GenericList<number>(); numberList.addItem(10); numberList.addItem(20); console.log(numberList.getItem(0)); // 10

GenericList<T> ํด๋ž˜์Šค๋Š” ์–ด๋–ค ํƒ€์ž…์ด๋“  ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ตฌํ˜„ํ•ด์š”. stringList๋Š” ๋ฌธ์ž์—ด๋งŒ, numberList๋Š” ์ˆซ์ž๋งŒ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ํƒ€์ž… ์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•˜๋ฉด์„œ๋„ ์ฝ”๋“œ๋Š” ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์ฃ .

๐Ÿ’ก ์ œ๋„ค๋ฆญ ์ œ์•ฝ ์กฐ๊ฑด (Constraints)

๋•Œ๋กœ๋Š” ์ œ๋„ค๋ฆญ ํƒ€์ž…์ด ํŠน์ • ์กฐ๊ฑด์„ ๋งŒ์กฑํ•ด์•ผ ํ•  ๋•Œ๊ฐ€ ์žˆ์–ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ œ๋„ค๋ฆญ์œผ๋กœ ๋ฐ›์€ ์ธ์ž๊ฐ€ length ์†์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ์‹ถ์„ ๋•Œ๊ฐ€ ๊ทธ๋ ‡์ฃ . ์ด๋•Œ extends ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ œ๋„ค๋ฆญ ์ œ์•ฝ ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์–ด์š”.

interface Lengthwise { length: number; } function logLength<T extends Lengthwise>(arg: T): T { console.log(arg.length); // ์ด์ œ T๋Š” length ์†์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Œ์ด ๋ณด์žฅ๋ผ์š”. return arg; } logLength("hello"); // OK, ๋ฌธ์ž์—ด์€ length ์†์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์š”. logLength([1, 2, 3]); // OK, ๋ฐฐ์—ด๋„ length ์†์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์š”. // logLength(10); // ์ปดํŒŒ์ผ ์—๋Ÿฌ: number ํƒ€์ž…์€ length ์†์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์•„์š”.

T extends Lengthwise๋Š” T๊ฐ€ ๋ฐ˜๋“œ์‹œ Lengthwise ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜, Lengthwise ์ธํ„ฐํŽ˜์ด์Šค์™€ ํ˜ธํ™˜๋˜๋Š” ํ˜•ํƒœ์—ฌ์•ผ ํ•จ์„ ์˜๋ฏธํ•ด์š”. ์ด๋ฅผ ํ†ตํ•ด ์ œ๋„ค๋ฆญ ํƒ€์ž… T๊ฐ€ ํŠน์ • ์†์„ฑ์ด๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Œ์„ ๋ณด์žฅํ•˜๊ณ , ๋” ์•ˆ์ „ํ•˜๊ฒŒ ํ•ด๋‹น ์†์„ฑ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ผ์š”.

๐Ÿคฏ ์ œ๋„ค๋ฆญ๊ณผ ๊ด€๋ จ๋œ ํ”ํ•œ ์˜คํ•ด์™€ ํ•ด๊ฒฐ์ฑ…

0๏ธโƒฃ ์ œ๋„ค๋ฆญ ๊ธฐ๋ณธ๊ฐ’ ์„ค์ • (Default Generic Types)

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ 2.3๋ถ€ํ„ฐ ์ œ๋„ค๋ฆญ ํƒ€์ž…์— ๊ธฐ๋ณธ๊ฐ’์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์–ด์š”. ์ด๋Š” ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ๋ช…์‹œํ•˜์ง€ ์•Š์•˜์„ ๋•Œ ํŠน์ • ๊ธฐ๋ณธ ํƒ€์ž…์ด ์‚ฌ์šฉ๋˜๋„๋ก ํ•˜์—ฌ, ์œ ์—ฐ์„ฑ์„ ๋” ๋†’์—ฌ์ค˜์š”.

interface FetchResult<T = any> { data: T; status: number; message?: string; } const successResult: FetchResult = { data: { id: 1, name: 'Test' }, status: 200 }; // T๋ฅผ ๋ช…์‹œํ•˜์ง€ ์•Š์•„๋„ ๊ธฐ๋ณธ๊ฐ’์ธ any๊ฐ€ ์ ์šฉ๋˜์–ด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•„์š”. console.log(successResult.data.id); const errorResult: FetchResult<string> = { data: "Error occurred", status: 500 }; // string ํƒ€์ž…์„ ๋ช…์‹œํ•˜๋ฉด T๋Š” string์ด ๋ผ์š”. console.log(errorResult.data.toUpperCase());

FetchResult<T = any>์ฒ˜๋Ÿผ T์— any๋ฅผ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜๋ฉด, ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ๋ช…์‹œํ•˜์ง€ ์•Š์•˜์„ ๋•Œ any๋กœ ๋™์ž‘ํ•ด์š”. ์ด๋Š” ๊ธฐ์กด ์ฝ”๋“œ์™€์˜ ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•˜๊ฑฐ๋‚˜, ํŠน์ • ์ƒํ™ฉ์—์„œ ํƒ€์ž… ์ถ”๋ก ์ด ์–ด๋ ค์šด ๊ฒฝ์šฐ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์–ด์š”. ํ•˜์ง€๋งŒ any ์‚ฌ์šฉ์€ ์ตœ์†Œํ™”ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๋Š” ์ ์„ ํ•ญ์ƒ ๊ธฐ์–ตํ•ด ์ฃผ์„ธ์š”.

1๏ธโƒฃ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ œ๋„ค๋ฆญ ํƒ€์ž…๊ณผ ์ œ์•ฝ ์กฐ๊ฑด

ํ•˜๋‚˜์˜ ํ•จ์ˆ˜๋‚˜ ์ธํ„ฐํŽ˜์ด์Šค์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์–ด์š”. ๊ฐ ์ œ๋„ค๋ฆญ ํƒ€์ž…์€ ๋…๋ฆฝ์ ์ธ ์ œ์•ฝ ์กฐ๊ฑด์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ณ ์š”. ์ด๋Š” ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋‚˜ ํ•จ์ˆ˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ์ •์˜ํ•  ๋•Œ ์œ ์šฉํ•ด์š”.

// K๋Š” string ๋˜๋Š” number๋ฅผ ํ™•์žฅํ•ด์•ผ ํ•˜๊ณ , V๋Š” ์–ด๋–ค ํƒ€์ž…์ด๋“  ๊ฐ€๋Šฅํ•ด์š”. function createKeyValue<K extends string | number, V>(key: K, value: V): { key: K; value: V } { return { key, value }; } const myKeyValue = createKeyValue("name", "๋ธ”๋ฃจ"); console.log(myKeyValue.key, myKeyValue.value); // "name" "๋ธ”๋ฃจ" // const invalidKeyValue = createKeyValue(true, 123); // ์ปดํŒŒ์ผ ์—๋Ÿฌ: K๋Š” string | number๊ฐ€ ์•„๋‹ˆ์—์š”. interface Dictionary<K extends string, V> { [key: string]: V; } const stringDict: Dictionary<string, number> = { a: 1, b: 2 }; // const numberDict: Dictionary<number, string> = { 1: "a" }; // ์ปดํŒŒ์ผ ์—๋Ÿฌ: K๋Š” string์ด์–ด์•ผ ํ•ด์š”. // ์œ„ ์ฝ”๋“œ์—์„œ K extends string์€ ์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ฒ˜์˜ ํ‚ค๊ฐ€ string์ด์–ด์•ผ ํ•œ๋‹ค๋Š” ์ œ์•ฝ ์กฐ๊ฑด๊ณผ ์ผ์น˜ํ•ด์•ผ ํ•ด์š”.

createKeyValue ํ•จ์ˆ˜๋Š” K์™€ V ๋‘ ๊ฐ€์ง€ ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ๋ฐ›์•„์š”. K๋Š” string ๋˜๋Š” number๋กœ ์ œ์•ฝ๋˜์–ด ์žˆ์–ด ํ‚ค๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž…์„ ์ œํ•œํ•˜๊ณ  ์žˆ์ฃ . Dictionary ์ธํ„ฐํŽ˜์ด์Šค ๋˜ํ•œ ํ‚ค๊ฐ€ string์ด์–ด์•ผ ํ•œ๋‹ค๋Š” ์ œ์•ฝ ์กฐ๊ฑด์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์š”. ์ด์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ํ™œ์šฉํ•˜๋ฉด ๋”์šฑ ์ •๊ตํ•œ ํƒ€์ž… ์ •์˜๊ฐ€ ๊ฐ€๋Šฅํ•ด์š”.

2๏ธโƒฃ keyof์™€ typeof ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ

์ œ๋„ค๋ฆญ๊ณผ keyof, typeof ์—ฐ์‚ฐ์ž๋ฅผ ์กฐํ•ฉํ•˜๋ฉด ๊ฐ์ฒด์˜ ์†์„ฑ ์ด๋ฆ„์„ ํƒ€์ž…์œผ๋กœ ๋ฐ›๊ฑฐ๋‚˜, ๊ธฐ์กด ๋ณ€์ˆ˜์˜ ํƒ€์ž…์„ ์ถ”๋ก ํ•˜์—ฌ ๋”์šฑ ์œ ์—ฐํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ ํƒ€์ž…์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”.

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; } const user = { name: "๋ธ”๋ฃจ", age: 10, email: "blue@example.com" }; const userName = getProperty(user, "name"); // userName์˜ ํƒ€์ž…์€ string console.log(userName); // "๋ธ”๋ฃจ" const userAge = getProperty(user, "age"); // userAge์˜ ํƒ€์ž…์€ number console.log(userAge); // 10 // const userAddress = getProperty(user, "address"); // ์ปดํŒŒ์ผ ์—๋Ÿฌ: user ๊ฐ์ฒด์—๋Š” 'address' ์†์„ฑ์ด ์—†์–ด์š”. // typeof์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ ์˜ˆ์‹œ type UserType = typeof user; function updateProperty<T extends UserType, K extends keyof T>(obj: T, key: K, value: T[K]): T { return { ...obj, [key]: value }; } const updatedUser = updateProperty(user, "age", 11); console.log(updatedUser); // { name: "๋ธ”๋ฃจ", age: 11, email: "blue@example.com" } // updateProperty(user, "age", "์—ดํ•œ์‚ด"); // ์ปดํŒŒ์ผ ์—๋Ÿฌ: 'age' ์†์„ฑ์€ number ํƒ€์ž…์ด์–ด์•ผ ํ•ด์š”.

getProperty ํ•จ์ˆ˜๋Š” keyof T๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ K๊ฐ€ T์˜ ์œ ํšจํ•œ ์†์„ฑ ์ด๋ฆ„์ž„์„ ๋ณด์žฅํ•ด์š”. ๊ทธ๋ฆฌ๊ณ  T[K]๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ์†์„ฑ์˜ ํƒ€์ž…์„ ์ •ํ™•ํ•˜๊ฒŒ ๋ฐ˜ํ™˜ํ•˜์ฃ . updateProperty ํ•จ์ˆ˜์—์„œ๋Š” typeof๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ์กด ๊ฐ์ฒด์˜ ํƒ€์ž…์„ ์ถ”์ถœํ•˜๊ณ , ์ด๋ฅผ ์ œ๋„ค๋ฆญ ์ œ์•ฝ ์กฐ๊ฑด์œผ๋กœ ํ™œ์šฉํ•˜์—ฌ ๋”์šฑ ์•ˆ์ „ํ•œ ์—…๋ฐ์ดํŠธ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ์–ด์š”. ์ด ํŒจํ„ด์€ ๊ฐ์ฒด์˜ ์†์„ฑ์— ๋™์ ์œผ๋กœ ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ๋•Œ ๋งค์šฐ ์œ ์šฉํ•ด์š”.

๐Ÿ“ ์ •๋ฆฌํ•˜๋ฉฐ: ์ œ๋„ค๋ฆญ ๋งˆ์Šคํ„ฐํ•˜๊ธฐ

0๏ธโƒฃ ํ•ต์‹ฌ ์š”์•ฝ

์˜ค๋Š˜ ์šฐ๋ฆฌ๋Š” ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ œ๋„ค๋ฆญ์˜ ๊นŠ์€ ์„ธ๊ณ„๋ฅผ ํƒํ—˜ํ•ด ๋ณด์•˜์–ด์š”. ์ œ๋„ค๋ฆญ์€ any ํƒ€์ž…์˜ ๋‹จ์ ์„ ๋ณด์™„ํ•˜๊ณ , ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉ์„ฑ๊ณผ ํƒ€์ž… ์•ˆ์ •์„ฑ์„ ๋™์‹œ์— ๋†’์—ฌ์ฃผ๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์…จ์„ ๊ฑฐ์˜ˆ์š”.
ํ•จ์ˆ˜, ์ธํ„ฐํŽ˜์ด์Šค, ํด๋ž˜์Šค์—์„œ ์ œ๋„ค๋ฆญ์„ ํ™œ์šฉํ•˜๋Š” ๊ธฐ๋ณธ ๋ฐฉ๋ฒ•๋ถ€ํ„ฐ extends๋ฅผ ์ด์šฉํ•œ ์ œ์•ฝ ์กฐ๊ฑด ์„ค์ •, ๊ทธ๋ฆฌ๊ณ  keyof, typeof์™€ ๊ฐ™์€ ์—ฐ์‚ฐ์ž๋“ค๊ณผ์˜ ์กฐํ•ฉ๊นŒ์ง€ ๋‹ค์–‘ํ•œ ์‹ค์šฉ์ ์ธ ํŒจํ„ด๋“ค์„ ์‚ดํŽด๋ณด์•˜์–ด์š”. ํŠนํžˆ ์ œ๋„ค๋ฆญ ๊ธฐ๋ณธ๊ฐ’ ์„ค์ •์€ ์œ ์—ฐ์„ฑ์„ ๋”ํ•ด์ฃผ์ง€๋งŒ any ๋‚จ์šฉ์€ ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ๋„ ๊ฐ•์กฐ ๋“œ๋ ธ์ฃ .

1๏ธโƒฃ ๋‹ค์Œ ์•ก์…˜: ์ง์ ‘ ์ ์šฉํ•ด ๋ณด๊ธฐ

์ œ๋„ค๋ฆญ์€ ํ•œ ๋ฒˆ์— ๋ชจ๋“  ๊ฒƒ์„ ์ดํ•ดํ•˜๊ธฐ๋ณด๋‹ค๋Š”, ์ง์ ‘ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ ๊ฒฝํ—˜ํ•ด ๋ณด๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ค‘์š”ํ•ด์š”. ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”„๋กœ์ ํŠธ์—์„œ ๋ฐ˜๋ณต๋˜๋Š” ์ฝ”๋“œ ํŒจํ„ด์ด ์žˆ๋‹ค๋ฉด ์ œ๋„ค๋ฆญ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆฌํŒฉํ† ๋งํ•ด ๋ณด์„ธ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ณตํ†ต์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜๋‚˜ ์ƒํƒœ ๊ด€๋ฆฌ ๊ฐ์ฒด ๋“ฑ์— ์ œ๋„ค๋ฆญ์„ ์ ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”.
์ฒ˜์Œ์—๋Š” ์–ด๋ ต๊ฒŒ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ, ๊พธ์ค€ํžˆ ์—ฐ์Šตํ•˜๋‹ค ๋ณด๋ฉด ์–ด๋А์ƒˆ ์ œ๋„ค๋ฆญ์„ ์ž์œ ์ž์žฌ๋กœ ๋‹ค๋ฃจ๋Š” ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ๊ณ ์ˆ˜๊ฐ€ ๋˜์–ด ์žˆ์„ ๊ฑฐ์˜ˆ์š”. ๋ณต์žกํ•œ ํƒ€์ž…์„ ๋‹ค๋ฃจ๋Š” ๋ฐ ์žˆ์–ด ์ œ๋„ค๋ฆญ์€ ์—ฌ๋Ÿฌ๋ถ„์˜ ๊ฐ€์žฅ ๋“ ๋“ ํ•œ ์กฐ๋ ฅ์ž๊ฐ€ ๋  ๊ฒƒ์ด๋ผ๊ณ  ํ™•์‹ ํ•ด์š”!

๐Ÿ“ฎ ์ฐธ๊ณ 

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