개념/배경

Parameters는 TypeScript가 제공하는 제네릭 유틸리티 타입으로, 특정 함수 타입의 매개변수 타입들을 튜플로 추출하는 데 사용됨 함수 래핑, 고차 함수, 어댑터 계층에서 기존 함수 시그니처를 재사용해 타입 안정성을 유지하고 중복 선언을 줄이는 목적에 적합함

문법

type Parameters<T extends (...args: any) => any> = T extends (
  ...args: infer P
) => any
  ? P
  : never;
  • T가 함수 타입이면 매개변수 목록을 튜플 타입 P로 추출
  • T가 함수 타입이 아니면 never 반환
  • 추출 결과는 튜플이므로 인덱스 접근, 스프레드, 부분 적용 등 튜플 연산과 조합 가능

사용 예시

기본 추출

function greet(name: string, age: number) {
  return `Hello, ${name}. You are ${age} years old`;
}

type GreetParameters = Parameters<typeof greet>; // [name: string, age: number]

매개변수 타입 재사용

type GreetParameters = Parameters<typeof greet>;
const newGreet = (...args: GreetParameters) => greet(...args);

위와 같이 스프레드와 결합해 기존 함수의 매개변수 시그니처를 그대로 보존하는 래퍼를 작성 가능함 시그니처 변경 시 컴파일 시점에 파급 오류가 발생하므로 타입 드리프트를 방지하는 효과가 있음

비동기 함수에도 동일하게 적용 가능함 매개변수 추출은 반환 타입과 무관하며 Promise 여부에 영향 받지 않음

동작 포인트

  • infer 키워드를 사용한 조건부 타입으로 매개변수 튜플 P를 도출하는 구조
  • 튜플에 라벨이 표시될 수 있으나 라벨은 가독성 보조 요소이며 타입 호환성에는 영향이 크지 않음
  • any에 대한 Parameters는 any[]로 간주될 수 있어 타입 안전성이 약해짐 가능한 한 구체적인 함수 타입을 대상으로 사용 권장

주의 사항

  • 함수 타입이 아닌 입력은 항상 never가 됨
type NotAFunction = Parameters<number>; // never
  • 오버로드가 있는 함수 타입을 대상으로 사용할 때 의도한 시그니처와 추출 결과가 어긋날 수 있음 가능한 한 명시적인 함수 타입 별칭을 만들어 두고 해당 타입에 대해 Parameters를 적용하는 방식 권장
  • 매개변수에 this 바인딩 타입이 있는 함수의 경우, 호출 시그니처 정의 방식에 따라 결과가 달라질 수 있음 this 파라미터를 분리한 호출 시그니처를 명시해 예측 가능성 확보 권장

베스트 프랙티스

  • 기존 함수의 매개변수 타입을 재사용하는 래퍼, 프락시, 데코레이터, 로깅 헬퍼 등에 적극 활용
  • API 경계에서 입력 검증 로직과 타입을 일치시키기 위해 Parameters 결과를 폼 파서나 밸리데이터와 연계
  • 팀 규칙으로 any를 허용하는 Parameters 사용을 제한하고, 구체 타입 기반으로만 사용하도록 가이드

마무리

Parameters는 함수 타입의 매개변수 목록을 튜플로 추출해 재사용성과 타입 안전성을 동시에 확보하는 유틸리티 타입임 조건부 타입과 infer를 기반으로 동작하며, 함수가 아닌 타입에는 never를 반환함 과도한 중복 선언을 줄이고 래퍼 함수의 타입 드리프트를 방지하는 데 실용적임

참고자료