7-1. Generic Type Variable and Generic Function
/* Generics */
function func<T>(value: T): T {
return value;
}
let num = func(10);
num.toFixed();
// num.toUpperCase(); // error
let str = func("string");
str.toUpperCase();
let bool = func(true);
// explicit typing
let arr = func<[number, number, number]>([1, 2, 3]);
// 타입 단언을 이용할수도 있다.
let arr2 = func([1, 2, 3] as [number, number, number]);
- generic은 “일반적인”, “포괄적인”이란 뜻을 가지고 있다. 뭐에 대해 포괄적이라는 것일까?
- 바로 타입이다. **Generic type variable(제네릭 타입 변수)**를 이용하면 타입을 미리 지정하지 않고 상황에 따라 필요한 타입에 “포괄적인” 코드를 작성할 수 있다.
- 참고로 (Generic) Type Variable은 (Generic) Type Parameter라고도 불린다.
Syntax
- generic type variable은 꺽쇠
<>를 통해 표현한다. 제네릭 타입 이름은 어떤 것으로 해도 상관 없으나, 보통 T를 가장 많이 사용한다.
- 위에서처럼 generic type variable을 이용해서 함수를 만드려면 함수 이름뒤에 꺽쇠 형식으로 generic type variable을 명시해준 후, parameter의 type과 return type에 이름붙인 generic type variable 이름을 사용해주면 된다.
- 실제로 제네릭 함수인
func이 사용되는 예시를 확인해보면,
- argument로
number type인 10을 넣은 경우에는 리턴타입 역시 number이기 때문에 toFixed()등의 메소드를 사용할 수 있는 것을 확인할 수 있다.
- 마찬가지로
string이나 boolean 타입의 입력값을 넣는 경우에도 리턴값은 입력값과 같은 타입을 가지는 것을 확인할 수 있다.
Generic Function 호출시 Explicit하게 타입 지정하는 방법
- 예를들어
[1, 2, 3]을 그냥 넣는 경우, 일반 array type으로 타입 추론이 일어나게 된다.
- 하지만 만약 해당 값을
[number, number, number] 형태의 튜플로 인식시키고 싶다면, 함수 호출시에도 함수 이름 뒤에 꺽쇠를 활용하여 입력 타입을 직접 지정해주면 된다.
- 물론 이전에 배웠던 타입 단언(
as) 기능을 사용하는 방법도 있다.
7-2. 제네릭 타입 변수 응용하기(함수에서)
두개 이상의 타입 변수 사용하기
/* multiple type variables */
function swap<T, U>(a: T, b: U) {
return [b, a];
}
const [a, b] = swap("1", 2);
- 이와 같이 꺽쇠 안에 여러개의 타입 변수를 선언할 수 있다.
배열, 튜플로 사용하기
/* type variable for array element */
function returnFirstValue<T>(arr: T[]){
return arr[0];
}
let num = returnFirstValue([1, 2, 3]);
/* type variable for tuple */
function returnFirstValue2<T>(arr: [T, ...unknown[]]){
return arr[0];
}
let num2 = returnFirstValue2([1, "2", false]);
- 함수에서
arr[0]을 리턴하고 있는데, 이처럼 배열 인덱스를 통해서 배열/튜플의 값에 접근하기 위해서는 해당 타입이 배열 또는 튜플이라는 보장이 필요하다.
- 따라서 파라미터에 그냥 T를 사용하는 것이 아니라, 배열/튜플임을 명시해주어야 한다.
- 배열의 경우 그냥
T[] 이렇게 하면 되지만,
- 튜플의 경우 조금 특이하다.
- 함수 내에서 튜플의 첫번째 원소에만 접근하기 때문에 첫번째 원소는 타입 변수를 사용해서 표기해주되, 나머지는 unknown배열에 대한 destructuring 문법을 사용해서 튜플 타입을 구현할 수 있다.
extends 키워드 사용하여 조건 달기