타입을 미리 정의하지 않고 사용하는 시점에 원하는 타입을 정의해서 쓸 수 있는 문법
function getText<T>(text: T): T {
return text;
}
위 예시 코드처럼 괄호 안에 타입을 적는다. 함수의 파라미터의 역할을 유사하게 하기 때문에 만약 지정된 타입과 다른 타입을 넘긴다면 아래와 같은 에러가 발생한다. 'number' 형식의 인수는 'string' 형식의 매개 변수에 할당될 수 없다고 설명한다.
앞서 제네릭은 타입을 미리 정의하지 않고 호출할 때 타입을 정의한다고 했다. 그 이유는 반복되는 타입 코드를 줄여주기 때문이다.
만약 아래처럼 제네릭을 사용하지 않는 상태의 코드가 있다고 가정해보자.
function getText(text: string): string {
return text;
}
function getNumber(num: number): number {
return num;
}
2개의 함수는 반환 타입만 다르다. 함수의 기능은 유사하지만 반환 타입이 달라 별도의 함수로 구현했다. 저런식으로 같은 기능을 하는 함수를 계속 만들게 되면 중복되는 코드가 너무 많이 생긴다.
any
타입을 사용해서 모든 타입에 대응한다는 방법은 사실상 타입스크립트의 장점 에러 사전 방지를 포기한다는 것이다.
제네릭으로 타입을 정의할 때 더 정확한 타입을 정의할 수 있게 도와준다.
제네릭을 그냥 사용했을 때 아무 타입이나 받아서 쓸 수 있다. 만약, 모든 타입이 아닌 특정 타입들만 받고 싶은 상황에 타입 제약을 걸어준다.
function getText<T extends string>(text: T): T {
return text;
}
먼저 keyof
부터 알아본다.
keyof
: 특정 타입의 키 값을 추출해서 문자열 유니언 타입으로 변환type PersonKey = keyof {
name: string;
age: number;
}
객체의 키를 PersonKey
라는 타입 별칭에 대입했다.
위 사진처럼 객체의 키가 유니언 타입으로 변환되어 있는 것을 확인할 수 있다.
function printKey<T extends keyof { name: string; age: number; }>(value: T) {
console.log(value);
}
printKey()
함수의 제네릭은 파라미터인 value
에 연결되어 있기 때문에 함수를 호출할 때 넘길 수 있는 인자는 name
과 age
이다.