kakasoo

infer R 타입을 이용한 GetReturnType 본문

프로그래밍/TypeScript

infer R 타입을 이용한 GetReturnType

카카수(kakasoo) 2023. 2. 12. 00:17
반응형

Type-Challenge의 문제 설계가 무척이나 잘 되어 있다고 느낀다.

그냥 타입스크립트를 평소에 쓰기만 했던 사람이 Type-Challenge의 문제들을 처음 푼다면 매우 답답할 것이다.

나는 분명 타입스크립트로 서비스를 개발하고 있는 개발자인데 Easy로 되어 있는 문제들도 풀기 어렵지 않은가 하고.

이는 타입스크립트를 사용한다는 말이 만들어낸 착각 같다.

 

타입스크립트 개발자란 어떻게 보면 그냥 파라미터와 리턴에 타입을 지정하거나 이미 만들어진 타입을 쓴다는 거고,

정확하게 구분한다면 남이 만든 타입을 쓰는 사람과 커스텀 타입을 구현할 수 있는 사람으로 나눠야 마땅할 것이다.

내가 직접 타입을 만드는 것, 어떻게 보면 라이브러리에 들어갈 타입을 구현해내는 것은 그저 쓰는 것과 전혀 다른 일이다.

타입 레벨에서의 코딩이 가능한 개발자여야 진짜 타입스크립트 개발자가 아닐까.

이번 GetReturnType은, infer keyword를 다룬다.

 

type MyReturnType<T> = T extends ((...args:any[]) => infer R) ? R : never;

infer keyword는 conditional한 구문을 다루는 extends에서 사용되며, 타입을 확정짓지 않는 상태에서 조건을 만드는 데에 쓰인다.
즉, 제너릭 구간이 아니라, 타입에 대한 정의 구간에서 사용된다고 볼 수 있다.
이는 조건부 타입을 만드는 데에 매우 유용한데, Return Type에서도 동일하게 쓰였다.
아직 타입이 확정되지 않았지만, R이라는 정의되지 않은 타입이 반환되는 함수라면, 그 R 타입을 가라키는 타입, 즉 리턴 타입이다.
이는 R이라는 타입이, 인자를 주는 시점에 호출되면서도, 제너릭처럼 모든 경우의 수를 작성할 필요를 없앤다.

 

type GetFirstArgumentOfAnyFunction<T> = T extends (
  first: infer First,
  ...args: any[]
) => any
  ? First
  : never

type PromiseReturnType<T> = T extends Promise<infer Return> ? Return : T
type ArrayType<T> = T extends (infer Item)[] ? Item : T
type FirstLetter <T> = T extends `${infer R}${string}` ? R : never;

이렇게 함수의 첫번째 파라미터 타입을 가져오게도 할 수 있고,
Promise를 풀었을 때의 값이 무엇인지,
Array의 각 요소 타입이 무엇인지,
문자열의 첫 번째 글자가 무엇인지를 가져오는 것처럼, 제너릭으로 구현하기에는 상당한 시간이 걸리는 걸을 일괄적으로 처리할 수 있다.

반응형