blog
Pick 대신 인덱스 접근 타입을 써야 하는 경우
Front-end / TypeScript#TypeScript#Pick#Indexed Access Types#유틸리티 타입
에러
버튼 컴포넌트의 color prop 타입을 재사용하려고 Pick을 썼더니 이런 에러가 났다.
Type 'Pick<CommonBtnProps, "color">' is not assignable to type '"neutralGray" | "brand" | "darkGray" | ... | undefined'.
interface CommonBtnProps {
color?: 'neutralGray' | 'brand' | 'darkGray' | 'gray';
size?: 'sm' | 'md';
}
interface IconBtnProps {
color?: Pick<CommonBtnProps, 'color'>; // ❌
}
원인
Pick<T, K>는 객체 타입을 만든다.
type A = Pick<CommonBtnProps, 'color'>;
// { color?: 'neutralGray' | 'brand' | 'darkGray' | 'gray' }
color 속성에 필요한 것은 문자열 유니온인데, { color?: ... } 객체를 넣었으니 타입이 맞지 않는다.
해결: 인덱스 접근 타입
속성 하나의 값 타입만 꺼내려면 T['key']를 쓴다.
type ButtonColor = CommonBtnProps['color'];
// 'neutralGray' | 'brand' | 'darkGray' | 'gray' | undefined
interface IconBtnProps {
color?: ButtonColor;
}
선택 속성(?)에서 꺼내면 undefined가 포함된다. 필수 값으로 쓰려면 NonNullable<CommonBtnProps['color']>로 제거한다.
정리
| 목적 | 사용 |
|---|---|
| 일부 속성만 가진 객체 타입 | Pick<T, 'a' | 'b'> |
| 속성 하나의 값 타입 | T['a'] |
Pick은 "props 중 일부만 받는 컴포넌트"처럼 객체 형태를 재사용할 때 쓴다. 예를 들어 interface IconBtnProps extends Pick<CommonBtnProps, 'color'> {}는 올바른 사용이다.