일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Medium
- CS
- typescript
- 리트코드
- web
- OS
- 동적계획법
- Level3
- 코테연습
- 파이썬
- LeetCode
- 배열
- 웹프로그래밍
- Doitvue.js입문
- VUE
- Level1
- C++
- 백준
- 프로그래머스
- 고득점Kit
- python
- 자바스크립트
- react
- 리액트
- dp
- javascript
- Level2
- 카카오
- sql
- 프로그래밍
- Today
- Total
[TypeScript] 제네릭 본문
제네릭
내장 제네릭 & 제네릭이란?
제네릭 타입이란 타입스크립트에 내장된 타입이며 다른 타입과 연결된다.
제네릭 타입을 사용하면 보다 나은 타입 안정성을 확보할 수 있다.
const names: Array<string> = []; //string[]
names[0].split(' ');
const promise = new Promise<number>((resolve, reject) => {
setTimeout(() => {
resolve(10);
}, 2000);
});
promise.then(data => {
data.split(' '); // error : Property 'split' does not exist on type 'number'.
})
Generic Functions
제네릭 함수를 직접 만들어보자.
두 개의 객체를 인자로 받아 합치는 merge
함수이다.
function merge(objA: object, objB: object) {
return Object.assign(objA, objB);
}
const mergeObj = merge({name: 'Max'}, {age: 30});
mergeObj.age;// error
merge는 되지만 mereg된 객체의 속성에 접근할 수 없다. 타입스크립트에게는 object가 구체적인 타입이 아니기 때문에 미상의 두 객체의 인터섹션이 반환된다는 사실외에는 추론할 수가 없다.
이때 제네릭 타입을 사용하면 두 매개변수가 서로 다른 타입이 될 수 있다고 타입스크립트에게 알려줄 수 있으므로 무작위의 객체 타입으로 작업하는 것이 아닌 다양한 타입 데이터를 얻고자 한다는 것을 타입스크립트가 인식하게 되고 해당 객체들의 인터섹션을 반환하므로 mergeObj
에 저장되는 데이터가 두 입력값 데이터의 인터섹션임을 타입스크립트가 인식할 수 있게 된다.
대체로 첫 번째 인자는 T, 두 번째 인자는 U로 쓴다.
function merge<T, U>(objA: T, objB: U) {
return Object.assign(objA, objB);
}
console.log(merge({name: 'Max'}, {age: 30}));
const mergeObj = merge({name: 'Max'}, {age: 30});
mergeObj.age;
Constraints
extends
키워드를 통해 제네릭 타입에 특정한 제약 조건을 설정할 수도 있다.
function merge<T extends object, U extends object>(objA: T, objB: U) {
return Object.assign(objA, objB);
}
속성 제한
특정 타입을 지정해서 제한하는 것 외에 특정 속성을 가진 타입만 인수로 들어오도록 제한할 수 있다. length를 가진 타입만 인자로 들어올 수 있도록 제한해보자
interface Lengthy {
length : number;
}
function countAndDescription<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(countAndDescription('Hi there!'));
string, array는 받을 수 있지만 숫자를 입력하면 에러가 나는 것을 볼 수 있다.
console.log(countAndDescription('Hi there!'));
console.log(countAndDescription(['Hi', 'Hello']);
console.log(countAndDescription(10)); // error
keyof 제약조건
제네릭 타입을 다른 제네릭 타입의 키로 지정할 수도 있다. keyof
키워드를 사용한다.
function extractAndConvert<T extends object, U extends keyof T>(obj: T, key: U) {
return `Value ${obj[key]}`
}
console.log(extractAndConvert({name: 'Max'}, 'name'));
제네릭 클래스
클래스에도 제네릭을 사용할 수 있다.
class DataStorage<T extends string | number | boolean > {
private data: T[] = [];
addItem(item: T) {
this.data.push(item);
}
removeItem(item: T) {
this.data.splice(this.data.indexOf(item), 1);
}
getItems() {
return [...this.data];
}
}
const textStorage = new DataStorage<string>();
textStorage.addItem('Max');
textStorage.addItem('Manu');
console.log(textStorage.getItems());
const numberStorage = new DataStorage<number> ();
// const objStorage = new DataStorage<object>();
// const maxObj = {name: 'Max'};
// objStorage.addItem(maxObj);
// objStorage.addItem({name: 'Manu'});
// objStorage.removeItem(maxObj);
// console.log(objStorage.getItems());
제네릭 유틸리티 타입
파셜(Partial) 타입
객체 타입이나 인터페이스 중 하나를 일시적으로 선택적으로 바꿔서 포함된 모든 속성을 일시적으로 선택적으로 해야하는 경우에 사용할 수 있다. 타입스크립트에게 아직 해당 객체가 완전히 생성되지 않은 부분임으로 알리는 것이다.
interface CourseGoal {
title: string;
description: string;
completeUntil: Date;
}
function createCourseGoal(
title: string,
description: string,
date: Date
): CourseGoal {
let courseGoal: Partial<CourseGoal> = {};
courseGoal.title = title;
courseGoal.description = description;
courseGoal.completeUntil = date;
return courseGoal as CourseGoal;
}
Readonly
속성을 변경하거나 이 객체에 새 속성을 추가할 수 없도록 할 수 있다.
const names: Readonly<string[]> = ['Max', 'Sports'];
names.push('Manu'); // error
'Web > TypeScript' 카테고리의 다른 글
[이펙티브 타입스크립트] 3장 타입 추론 - 1 (item 19 ~ 22) (0) | 2023.03.16 |
---|---|
[TypeScript] 고급타입 (0) | 2022.08.24 |
[TypeScript] 인터페이스 (0) | 2022.08.19 |
[TypeScript] 클래스 (0) | 2022.08.17 |
[TypeScript] TypeScript 컴파일러 (0) | 2022.08.12 |