Dream๐Ÿฐng
article thumbnail

๐Ÿ’ [230315 TIL] Understanding TypeScript

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
profile

Dream๐Ÿฐng

@shoupeach

๐Ÿฐ Happy new rabbit! ๐Ÿฐ

profile on loading

Loading...