예시로 보는 타입스크립트 Generic Types

isTuna·2022년 3월 6일
23

Typescript

목록 보기
1/2
post-thumbnail
post-custom-banner

📝 이 포스트는 Typescript generic types를 번역하고 정리한 글입니다!

타입스크립트에서 함수는?

타입 스크립트를 다룰 때 우리는 어떤 타입을 가지고 작업하는지 알고 있습니다.

예를 들어 아래와 같은 log를 출력하는 함수가 있습니다.

const logAndReturn = (input: string): string => {
	console.log("input: ",input);
  	return input;
}

위의 함수에서는 당연히 입력도 string, 출력도 string으로 추정 가능합니다. 하지만 꼭 string 타입으로 제한해야 할까요? 그래야할까요? inputnumber를 넣으면 안될까요?

알다시피 타입스크립트에서는 정해진 타입이 아닌 다른 타입을 주어주면 에러를 냅니다. 그럼 numberstring도 사용할 수 있는 방법에는 어떤게 있을까요?

한가지 방법으로는 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>


profile
청소연구소 개발자 (2021. 05~ )
post-custom-banner

2개의 댓글

comment-user-thumbnail
2022년 3월 7일

간단하지만 깔끔한 설명이네요 좋은 글 감사합니다!

1개의 답글