반응형
# TypeScript
## 제네릭
- 제네릭 : Java 등의 언어에서 재사용성이높은 컴포넌트를 만들 때 자주 활용되는 특징. 한가지 타입 보다 여러 가지 타입에서 작동하는 컴포넌트를 생성하는데 사용된다.
기본 문법
function logText<T>(text: T): T {
console.log(text);
return text;
}
logText<string>('hi');
아래와 같이 인터페이스에 제네릭 선언 가능.
// 인터페이스에 제네릭 선언 방법
// interface Dropdown {
// value: string;
// selected: boolean;
// }
// const obj: Dropdown = { value: 'abc', selected: false };
interface Dropdown<T> {
value: T;
selected: boolean;
}
const obj: Dropdown<string> = { value: 'abc', selected: false };
기존 타입 정의 방식과 제네릭의 차이점 - 함수 중복 선언의 단점
- 아래와 같이 타입을 다르게 받기위해 중복되는 코드 사용하는것은 유지보수 측면에서 좋지 않음.
function logText(text: string) {
console.log(text);
//text.split('').reverse().join('');
return text;
}
function logNumber(num: number) {
console.log(num);
return num;
}
logText('hi');
logNumber(10);
기존 문법과 제네릭의 차이점 - 유니온 타입을 이용한 선언 방식의 문제점
- 아래와 같은 경우 string과 number의 교집합인 공통으로 접근할 수 있는 속성, API 내에서만 자동완성 제공하는 문제점 존재.
function logText(text: string | number) {
console.log(text);
return text;
}
logText('hi');
logText(10);
- 아래와 같이 변수로 받았을 경우 반환값에 대한 문제 발생.
const a = logText('hi');
a.split(''); // string과 number 타입이기 때문에 불가.
제네릭의 장점과 타입 추론에서의 이점
- 제네릭 사용 시 아래와 같이 사용 가능.
function logText<T>(text: T): T {
console.log(text);
return text;
}
const str = logText<string>('abc');
str.split('');
const login = logText<boolean>(true);
제네릭 실전 예제. (이메일, 상품 수량 선택 드롭박스)
- 방법1) 인터페이스와 유니온 사용하여 아래와 같이 가능.
interface Email {
value: string;
selected: boolean;
}
interface ProductNumber {
value: number;
selected: boolean
}
interface TrueFalse {
value: boolean;
selected: boolean
}
const emails: Email[] = [
{ value: 'naver.com', selected: true },
{ value: 'gmail.com', selected: false },
{ value: 'hanmail.net', selected: false },
];
const numberOfProducts: ProductNumber[] = [
{ value: 1, selected: true },
{ value: 2, selected: false },
{ value: 3, selected: false },
];
function createDropdownItem(item: Email | ProductNumber) {
const option = document.createElement('option');
option.value = item.value.toString();
option.innerText = item.value.toString();
option.selected = item.selected;
return option;
}
// NOTE: 이메일 드롭 다운 아이템 추가
emails.forEach(function (email) {
const item = createDropdownItem(email);
const selectTag = document.querySelector('#email-dropdown');
selectTag.appendChild(item);
});
numberOfProducts.forEach(function (product) {
const item = createDropdownItem(product);
const selectTag = document.querySelector('#product-dropdown');
selectTag.appendChild(item);
});
- 방법2) 인터페이스에 제네릭을 사용하여 아래와 같이 가능.
interface DropdownItems<T> {
value: T;
selected: boolean;
}
// interface Email {
// value: string;
// selected: boolean;
// }
// interface ProductNumber {
// value: number;
// selected: boolean
// }
// interface TrueFalse {
// value: boolean;
// selected: boolean
// }
const emails: DropdownItems<string>[] = [
{ value: 'naver.com', selected: true },
{ value: 'gmail.com', selected: false },
{ value: 'hanmail.net', selected: false },
];
const numberOfProducts: DropdownItems<number>[] = [
{ value: 1, selected: true },
{ value: 2, selected: false },
{ value: 3, selected: false },
];
function createDropdownItem(item: DropdownItems<string> | DropdownItems<number>) {
const option = document.createElement('option');
option.value = item.value.toString();
option.innerText = item.value.toString();
option.selected = item.selected;
return option;
}
// NOTE: 이메일 드롭 다운 아이템 추가
emails.forEach(function (email) {
const item = createDropdownItem(email);
const selectTag = document.querySelector('#email-dropdown');
selectTag.appendChild(item);
});
numberOfProducts.forEach(function (product) {
const item = createDropdownItem(product);
const selectTag = document.querySelector('#product-dropdown');
selectTag.appendChild(item);
});
제네릭의 타입 제한_1_.
// 제네릭의 타입 제한.
function logTextLength<T>(text: T[]): T[] {
console.log(text.length);
text.forEach(function (text) {
console.log(text);
});
return text;
}
logTextLength<string>(['hi', 'abc']);
제네릭의 타입 제한_2_정의된 타입으로 타입 제한.
// 제네릭 타입 제한 _ 정의된 타입 이용.
interface LengthType {
length: number;
}
function logTextLength<T extends LengthType>(text: T): T {
console.log(text.length);
return text;
}
logTextLength('a');
logTextLength(10); // 불가.
logTextLength({ length: 10 });
제네릭의 타입제한_3_keyof로 제네릭의 타입 제한하기
// 제네릭 타입 제한 _ keyof
interface ShoppingItem {
name: string;
price: number;
stock: number;
}
function getShoppingItemOption<T extends keyof ShoppingItem>(itemOption: T): T {
return itemOption;
}
getShoppingItemOption('name'); // ctrl + space 로 자동완성 확인.
반응형
'인프런 강의 학습 > TypeScript' 카테고리의 다른 글
TypeScript 11일차_실습 (0) | 2022.03.25 |
---|---|
TypeScript 9일차_클래스 (0) | 2022.03.21 |
TypeScript 8일차_이넘(Enum) (0) | 2022.03.20 |
TypeScript 7일차_연산자를 이용한 타입 정의 (0) | 2022.03.20 |
TypeScript 6일차_타입 별칭 (0) | 2022.03.19 |