ReturnType<T> 및 **Parameters<T>**는 TypeScript의 유틸리티 타입으로, 함수의 반환값 타입(ReturnType)이나 매개변수의 타입 배열(Parameters)을 자동으로 추론할 수 있게 해줍니다.
이는 애플리케이션의 다양한 부분 간 타입 일관성을 보장하고 제너릭 래퍼를 구현하는 데 특히 유용합니다.
사용 예시:
function fn(a: number, b: string): boolean { return b.length > a; } type FnReturn = ReturnType<typeof fn>; // boolean type FnParams = Parameters<typeof fn>; // [number, string]
함수 오버로드에 대한 주의사항: 함수 오버로드가 있을 때, ReturnType은 마지막 시그니처를 정의하며, Parameters는 가능한 모든 오버로드를 정의합니다:
function overloaded(x: number): number; function overloaded(x: string): string; function overloaded(x: any): any { return x; } type OverRet = ReturnType<typeof overloaded>; // any type OverParams = Parameters<typeof overloaded>; // [any]
즉, 유틸리티 타입의 타입화는 항상 모든 오버로드를 "볼" 수 있는 것은 아니기 때문에 정적 타입화가 덜 예측 가능해집니다.
ReturnType 및 Parameters를 사용하여 커스텀 함수의 모든 가능한 오버로드 타입을 각각 따로 정의할 수 있을까요?
답변:
아니요. 유틸리티 타입 ReturnType 및 Parameters는 함수의 "결합된" 시그니처만 분석합니다 — 구현을 위해 설명된 대로. 각 개별 오버로드의 타입을 가져오는 것은 불가능하며, 오직 최종 구현된 시그니처만 가능합니다.
예시:
type P = Parameters<typeof overloaded>; // [any], [number], [string]이 아님
이야기
개발자들은 ReturnType<T>를 사용하여 반환값의 타입을 타입화하기 위해 aroundMethod 래퍼를 작성했습니다. 이때 래퍼 함수가 오버로드된 함수에 적용되었습니다. 결과: 타입이 너무 일반적(any)하여 컴파일러가 반환값 불일치를 알리지 않았습니다. boolean 대신 string을 사용할 때 버그를 늦게 발견했습니다.
이야기
개발자가 Parameters<T>를 통해 여러 API 함수의 매개변수를 추론하려고 할 때 메서드의 오버로드를 고려하지 않았습니다. 이로 인해 [string, number] 대신 [any]가 기대되는 "잘못된" 타입 문제 발생. 유닛 테스트는 구현을 통해 오류를 잡아내지 못했으며, 실제 API 사용자는 프로덕션에서 버그를 겪었습니다.
이야기
JavaScript에서 TypeScript로 대규모 코드를 마이그레이션하면서 개발자들은 모두 ReturnType을 통해 타입화했습니다. 나중에 구현이 오버로드 선언과 매우 다르다는 것을 깨달았습니다. 이로 인해 잘못된 인자와 관련된 시나리오는 예상치 못한 런타임 예외(TypeError: x is undefined)를 발생시켰습니다.