Generics 1๏ธโฃ
What is Generics?
์ ๋ค๋ฆญ์ vanilla JavaScript์๋ ์๊ณ TypeScript์๋ง ์๋ ๊ฐ๋ ์ผ๋ก,
ํน์ ํ์ ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ์ฌ ํ์ ์์ ์ฑ์ ํ๋ณดํ ์ ์๋ ๊ธฐ๋ฒ์ด๋ค.
TypeScript์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํ๋ ์ ๋ค๋ฆญ ํ์
์ผ๋ก๋ Array
, Promise
๊ฐ ์๋ค.
// Array
const names: Array<string> = [];
/* Array์ ๋ํ ํ์
์ string์ผ๋ก ์ง์ ํ๋ฉด(= Generic)
์์ผ๋ก names ๋ฐฐ์ด์ ๋ค์ด์ฌ ๋ฐ์ดํฐ์ ํ์
์ด string์์ ์ถ๋ก ํจ */
// Promise
const promise: Promise<number> = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(10);
}, 2000);
});
promise.then(data => {
data.split(' '); // Error occurred
}
/* Promise์ ๋ํ ํ์
์ number๋ก ์ง์ ํ๊ธฐ ๋๋ฌธ์(= Generic)
promise์ ๋ฐํ๊ฐ ๋ํ number๋ก ์ถ๋ก ํ์ฌ split ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์์ */
Generic Functions
function merge(objA: object, objB: object) {
return Object.assign(objA, objB);
}
const mergedObj = merge({ name: 'Shou' }, { age: 29 });
mergedObj.name; // Error occurred
mergedObj.age; // Error occurred
์ ํจ์์์ merge
์ ๋ฐํ๊ฐ์ด object
์์ ์ถ๋ก ๊ฐ๋ฅํ์ง๋ง,
mergedObj
์ ํ์
์ด ์ ํํ { name; age; }
๋ผ๋ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ ๊ฒ์ด ์๋๊ธฐ ๋๋ฌธ์
mergedObj.name
, mergedObj.age
๋ก ์ ๊ทผํ๋ฉด ์ปดํ์ผ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
const mergedObj = merge({ name: 'Shou' }, { age: 29 }) as { name: string, age: number };
๋ก ํ๋ณํ์ ํ ์ ์์ง๋ง ๋งค์ฐ ๋ฒ๊ฑฐ๋กญ๋ค!!
์ด ๋ ์ ๋ค๋ฆญ์ ์ฌ์ฉํ๋ค๋ฉด?
function merge<T, U>(objA: T, objB: U) {
return Object.assign(objA, objB);
}
const mergedObj = merge({ name: 'Shou' }, { age: 29 });
์์ ๊ฐ์ด ์์ฑํ๊ฒ ๋๋ฉด merge
์ ์ ๋ฌ๋๋ ๋ ๋งค๊ฐ๋ณ์๊ฐ ์๋ก ๋ค๋ฅธ ํ์
์ด ๋ ์ ์๋ค๊ณ TypeScript์๊ฒ ์ ๋ฌํ๊ฒ ๋๋ค.
TypeScript๋ ๋ฌด์์์ ๊ฐ์ฒด ํ์ ์ด ์๋๋ผ ๋ค์ํ ํ์ ์ ๋ฐ์ดํฐ๋ฅผ ์ป๊ณ ์ ํ๋ค๊ณ ์ธ์ํ๊ฒ ๋๋ฉด์
mergeObj
์ ์ ์ฅ๋ ๋ฐ์ดํฐ๊ฐ ๋ ์ธ์์ Intersection์์ ์ถ๋ก ํ๋ค.
๋ํ ํ์ ์ ์ ์ธํ ๋ ๊ณ ์ ์ ์ผ๋ก ์ ํด๋๋ ๊ฒ์ด ์๋๋ผ ์์ฑํ ๋ ๋ช ์ํจ์ผ๋ก์จ ๋์ ์ผ๋ก ์ค์ ํ ์ ์๋ค๋ ์ฅ์ ์ด ์๋ค.
์ผ๋ฐ์ ์ผ๋ก ์ ๋ค๋ฆญ ํ์ ์ ์ฌ์ฉํ ๋ ์ฒซ๋ฒ์งธ ์๋ณ์๋ก๋ T, ๋๋ฒ์งธ ์๋ณ์๋ก๋ U๋ฅผ ์ ๋ฌํ๋ค.
Constraints
์ ๋ค๋ฆญ ํ์ ์ ๊ธฐ๋ฐ์ผ๋ก ํน์ ์ ์ฝ ์กฐ๊ฑด์ ์ค์ ํ ์ ์๋ค.
function merge<T extends object, U extends object>(objA: T, objB: U) {
return Object.assign(objA, objB);
}
const mergedObj = merge({ name: 'Shou', hobbies: ['Game'] }, 29);
// Error occurred
extends
ํค์๋๋ฅผ ํ์ฉํด T
์ U
๊ฐ ์ด๋ค ๊ตฌ์กฐ๋ฅผ ๊ฐ์ ธ๋ ์๊ด์์ง๋ง '๊ฐ์ฒด'์ฌ์ผ ํ๋ค๋ ์ ๋ณด๋ฅผ ์ ๋ฌํ์๋ค.
mergedObj
์์๋ ๋๋ฒ์งธ ์ธ์๋ก ๊ฐ์ฒด๊ฐ ์๋ number
ํ์
์ ์ ๋ฌํ๊ธฐ ๋๋ฌธ์ ์ปดํ์ผ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
์ ์ฝ ์กฐ๊ฑด์๋ ๋ฌด์์ด๋ ์ง ์ง์ ์ด ๊ฐ๋ฅํ๋ค! T extends string, T extends string | number ... ๋จ, ๋ชจ๋ ์ ๋ค๋ฆญ์ ์ ์ฝ ์กฐ๊ฑด์ ์ค์ ํ ํ์๋ ์๋ค!
interface Lengthy {
length: number;
}
function countAndDescribe<T extends Lengthy>(element: T): [T, string] {
let descriptionText = 'Got no value.';
if (element.length === 1) {
descriptionText = 'Got 1 element.'
} else if (element.length > 1) {
descriptionText = 'Got ' + element.length + ' elements.';
}
return [element, descriptionText];
}
console.log(countAndDescribe('Hi there!'));
// ['Hi there', 'Got 9 elements.']
console.log(countAndDescribe(['Game', 'Piano']);
// [['Game', 'Piano'], 'Got 2 elements.']
์ ์ฝ ์กฐ๊ฑด์ ์ค์ ํจ์ผ๋ก countAndDescribe
์ ์ ๋ฌ๋๋ ์ธ์๊ฐ ๋ฌด์์ด๋ length
์์ฑ๋ ๋ฐํ๋จ์ ๋ช
์ํ ์ ์๋ค.
'๐ Study > TypeScript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[TS] Project Drag & Drop 1๏ธโฃ (2) | 2023.03.27 |
---|---|
[TS] Decorators 3๏ธโฃ (0) | 2023.03.24 |
[TS] Decorators 2๏ธโฃ (0) | 2023.03.22 |
[TS] Decorators 1๏ธโฃ (1) | 2023.03.20 |
[TS] Generics 2๏ธโฃ (0) | 2023.03.17 |