1. 제네릭의 타입 제한
function logTextLength<T>(text: T[]): T[] {
console.log(text.length);
text.forEach((text) => console.log(text));
return text;
}
logTextLength<string>(['hi', 'abc']);
logTextLength<string>('hi');
- 전달인자에 단순히 문자열만 넘기고 length 속성을 쓰면, 에러 발생
- 문자열을 전달해도 타입스크립트는 어떠한 타입이 들어올지 추론을 못해서 에러 발생
- length를 사용하고 싶으면 타입을 제한해서 사용
- T[]를 사용하면, T는 배열이기 때문에 length가 제공됨
- 함수 내에서는 제네릭 타입이 배열이라는 것을 알고 있어서, 배열 타입으로 가정하고 속성이나 api 제공
- 제네릭으로 받은 타입을 배열로 지정해서 함수 내부에서 배열의 특정 속성에 접근하는 것
2. 정의된 타입 이용하기
interface LengthType {
length: number;
}
function logTextLength<T extends LengthType>(text: T): T {
text.length;
return text;
}
logTextLength('a');
logTextLength(10);
logTextLength({ length: 10 });
- 특정 타입을 정의해서 넘겨받아 사용할 수 있음
- 인터페이스로 타입을 정의하고, 해당 타입을 extends 키워드로 제네릭으로 받은 타입으로 확장
- 제네릭으로 받은 타입은 인터페이스 타입의 하위 타입일 것이기 때문에 인터페이스 타입에 제공되는 속성이 항상 존재함
- 인터페이스 타입에서 제공되는 속성이 존재하는 상태에서 추가로 정의할 수 있다고 제한을 줌
- 제네릭에 들어갈 수 있는 타입들을 구분할 수 있음
- 인터페이스 타입이라는 정의되어 있는 타입을 이용해서 제네릭을 사용한다고 선언하게 되면 제네릭에 어느정도 제한이 생김
3. keyof 키워드 이용하기
interface ShoppingItem {
name: string;
price: number;
stock: number;
}
function getShoppingItemOption<T extends keyof ShoppingItem>(itemOption: T): T {
return itemOption;
}
getShoppingItemOption(10);
getShoppingItemOption<string>('a');
getShoppingItemOption('name');
- 인터페이스로 정의되어 있는 타입들 중에 하나만 받겠다고 함수를 제한할 수 있음
- 인터페이스의 한가지 속성만 받겠다 혹은 인터페이스에 정의되어있는 속성들만 받을 수 있게 제한 가능
- extends 키워드 : 기존에 정의되어있는 인터페이스, 타입들을 확장할 때 사용
- keyof 키워드까지 사용하게 되면 인터페이스의 키들 중에 한가지가 바로 제네릭의 타입이 됨
- 함수의 파라미터로는 인터페이스의 키들 중 한가지만 들어올 수 있다고 정의하는 것
- 즉, 제네릭에 들어올 수 있는 타입을 인터페이스의 키 값으로 제한
- 전달인자로 넘길수 있는 값은 인터페이스의 타입에서 키 값들만 들어갈 수 있다고 프리뷰 제공
참고 : 타입스크립트 입문 - 기초부터 실전까지