📝 이 포스트는 Typescript generic types를 번역하고 정리한 글입니다!
타입 스크립트를 다룰 때 우리는 어떤 타입을 가지고 작업하는지 알고 있습니다.
예를 들어 아래와 같은 log
를 출력하는 함수가 있습니다.
const logAndReturn = (input: string): string => {
console.log("input: ",input);
return input;
}
위의 함수에서는 당연히 입력도 string
, 출력도 string
으로 추정 가능합니다. 하지만 꼭 string
타입으로 제한해야 할까요? 그래야할까요? input
에 number
를 넣으면 안될까요?
알다시피 타입스크립트에서는 정해진 타입이 아닌 다른 타입을 주어주면 에러를 냅니다. 그럼 number
도 string
도 사용할 수 있는 방법에는 어떤게 있을까요?
한가지 방법으로는 any
를 타입으로 정하는 것입니다.
const logAndReturn = (input: any): any => {
console.log("input: ",input);
return input;
}
위와 같이 입력과 출력을 any
타입으로 지정하면 함수는 실행 되겠지만 외부에서 해당 함수가 어떤 타입을 출력할지 추론 할 수가 없습니다.
위 처럼 실행은 되겠지만 사실 Typescript를 쓰고 있다고 하긴 어렵습니다.
이때가 그 Generic Type가 유용해지는 경우입니다. Generic Type는 호출된 특정 함수의 타입을 식별하는데 사용할 수 있습니다.
Generic Type을 식별하려면 함수의 접두사로 <Type>
를 붙여야합니다. 여기서 Type
는 Generic Variable입니다.
💡 보통 Generic type으로
T
가 많이 사용됩니다. 규칙이 꼭 있는건 아닙니다!
위에서 보던 함수를 다시 Generic Typed 함수로 재구성 해봅시다.
const logAndReturn = <T>(input: T): T => {
console.log("input :", input);
return input;
}
이렇게 Generic Type으로 구현한 함수에 string
타입을 전달하고 싶으면 아래와 같이 사용하면 됩니다.
logAndReturn<string>('hello');
위와 같이 사용하면 string
으로 식별하고,
이를 number
타입으로 변경하면,
logAndReturn<number>(123);
위와 같이 number
로 식별합니다.
이처럼 Generic Type는 윗단에서 어떤 타입인지 몰라도 되면서도 올바른 유형의 타입을 유지할 수 있는 강력한 장점이 있습니다.
또한, 기존에 존재하는 타입이 아니라 User와 같은 Custom Interface를 정의해서 사용할 수도 있습니다.
interface User {
id: number;
name: string;
age: number;
}
logAndReturn<User>({id:1, name:'Henry', age:27});
이 경우 함수는 User 타입을 예상할 것입니다.
Generic Type를 특정 타입으로 제한하고 싶을 때 extends
를 사용해 제한 할수 있습니다.
const logAndReturn = <T extends string|number>(input: T): T => {
console.log("input :", input);
return input;
}
위와 같이 string|number
와 같은 union
타입을 지정할 수도 있고 전달 받은 객체의 속성값으로 제한 할 수도 있습니다.
<T,K extends keyof T>
간단하지만 깔끔한 설명이네요 좋은 글 감사합니다!