프로그래밍프론트엔드 개발자

TypeScript에서 분포형 타입(Distributive Types)이란 무엇이며, 어떤 곳에 사용되며 작업할 때 고려해야 할 특징은 무엇인가요?

Hintsage AI 어시스턴트로 면접 통과

답변

분포형 타입(Distributive Types)은 TypeScript에서 조건부 타입(T extends U ? X : Y)을 다룰 때 나타나는 특징입니다. extends의 왼쪽에 있는 타입 변수가 유니온일 때, TypeScript는 조건을 유니온의 각 요소에 분포시킵니다.

예시:

// "Test<A> | Test<B> | Test<C>" type Test<T> = T extends string ? () => string : () => number; type Result = Test<'A' | 'B' | 'C'>;

여기서 Result는 다음과 같이 분포됩니다:

  • Test<'A'> | Test<'B'> | Test<'C'>

사용 시기 — 범용 API 작성, 유니온에 대한 조작, 예를 들어 필터링 또는 패턴 매칭 등을 위해 사용됩니다.

특징:

  • T를 튜플 [T]로 감싸면 분포가 발생하지 않습니다. 이는 분포를 "비활성화"하는 방법입니다.
  • 분포는 타입 변수(리터럴이 아님)에 대해서만 작동합니다.

질문의 함정

질문: 타입 T[] extends number[] ? true : false는 분포형인가요?

정답: 아닙니다, 분포는 왼쪽에 배열이나 튜플로 감싸지 않은 타입 변수가 있을 때만 발생합니다. 예를 들어, 조건부 타입 T extends number ? ...는 분포하지만 T[] extends number[] ? ...는 아닙니다.


이 주제를 모르는 것 때문에 발생한 실제 오류 예시


이야기

프로젝트: React 컴포넌트의 props 유효성 검사 라이브러리. 유니온 prop를 엄격한 인터페이스로 변환하는 타입을 구현하려 했으나 분포를 모르고 타입이 예기치 않게 복잡해졌습니다(유니온 멤버의 속성이 혼합됨). 분포가 발생하지 않도록 [T]로 감싸면서 수정했습니다.


이야기

프로젝트: 모든 이벤트 타입을 하나의 핸들러 함수로 작성하고 있었습니다. 조건부 타입에서 함수가 각 이벤트 타입을 분포를 통해 받을 것이라고 예상했으나 명시적인 사용 없이 잘못된 처리를 하여 인수의 타입에 오류가 발생했습니다(유니온 대신 각 타입에 대한 별도의 호출).


이야기

프로젝트: 사용자 정의 유틸리티 타입(Exclude, Extract 등)을 만들 때 튜플과 배열에 대해서는 분포가 발생하지 않는다는 것을 잊었습니다. 그 결과, Exclude 타입이 배열에서 작동하지 않았습니다(예: 타입 Exclude<["a"|"b"], "b">는 "b"를 제거하지 않았습니다).