Typescript
[Typescript] 제네릭의 타입 제한
joy_lee
2022. 7. 13. 17:51
제네릭을 사용하면 여러 타입의 입력값을 처리할 수 있다. 하지만 타입이 명시되지 않아서 API를 사용할 수 없는 단점도 존재한다. 이런 상황에서 제네릭으로 입력받을 타입에 대한 힌트를 줄 수 있다.
제네릭의 타입 제한
1
2
3
4
5
6
7
8
9
10
|
// 제네릭의 타입 제한
// T[] : T타입 요소들이 들어간 array임을 명시
// 타입에 대한 힌트를 제공
function logTextLength<T>(text: T[]): T[] {
// 타입제한으로 .length가 가능해진다
console.log(text.length);
return text;
}
logTextLength<string>(['h', 'i']);
|
cs |
함수를 호출할 떼 제네릭으로 string을 전달하면, string[]타입을 입력받을 것이라는 힌트를 줄 수 있다.
그러면 함수 내부에서 array의 메소드인 .length를 사용할 수 있다.
T[]를 사용하지 않고 string[]을 입력받을 수도 있다. 하지만 함수 내부에서 API를 사용할 수 없다.
1
2
3
4
5
6
|
function logTextLength2<T>(text: T): T {
// console.log(text.length); error
return text;
}
logTextLength2<string[]>(['h', 'i']); // 입력은 가능함
|
cs |
정의된 타입을 이용해 제네릭 제한하기
이미 정의된 타입을 이용해 제네릭을 제한할 수 있다.
이 때는 extends를 사용한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// 제네릭 타입 제한 2 - 정의된 타입 이용하기
interface LengthType {
length: number;
}
// 인터페이스가 가진 하위 타입을 가지는 것들을 입력받는다고 명시함
function logTextLength<T extends LengthType>(text: T): T {
text.length;
return text;
}
logTextLength('a'); // string.length
logTextLength([1, 2, 3]) // array.length
logTextLength({ length: 10 }) // 하위 속성으로 length 가지고 있기 때문에 입력 가능
logTextLength(10); // 오류 : number.length 없음
|
cs |
이렇게 제네릭을 제한하면, extends 뒤의 하위타입을 함수 안에서 접근해 사용할 수 있다.
<T extends { toString: Function }> 으로 하위타입을 직접 명시할 수도 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
interface DropdownItem<T> {
value: T;
selected: boolean;
}
// <T extends { toString: Function }>
// toString이라는 함수 메소드를 가진 타입만 제네릭으로 받는다고 명시할 수 있다
function createDropdownItem<T extends { toString: Function }>(item: DropdownItem<T>) {
const option = document.createElement('option');
// item.value.toString() 사용 가능
option.value = item.value.toString();
option.innerText = item.value.toString();
option.selected = item.selected;
return option;
}
|
cs |
keyof 를 사용해 제네릭을 제한하기
keyof를 사용하면 keyof 다음에 오는 인터페이스가 가진 키들만 입력을 받게 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
// 제네릭의 타입 제한 3 - keyof
interface ShoppingItem {
name: string;
price: number;
stock: number;
}
// ShoppingItem이 가진 키들 중 한 가지가 제네릭이 된다
function getShoppingItemOption<T extends keyof ShoppingItem>(itemOption: T): T {
var item: ShoppingItem = {
name: "tumbler",
price: 12000,
stock: 10
}
console.log(item[itemOption]);
return itemOption;
}
// getShoppingItemOption(10); // 불가능
// ctrl + space로 넘길 수 있는 인자 확인 가능
getShoppingItemOption('price'); // 12000
|
cs |
위의 경우에는 ShoppingItem의 키인 'name', 'price', 'stock'만 입력할 수 있다. typeof를 사용하지만 하위 항목의 타입과는 관련이 없다.
console.log(typeof getShoppingItemOption('price')); // 'string'
참고한 사이트
강의