Item 14 타입 연산과 제너릭 사용으로 반복 줄이기
Remove Duplicate Types
코드 중복만큼 타입 중복도 많은 문제를 발생시킨다. 타입에 대한 중복을 제거하는 방법은..
타입에 이름 붙이기
인터페이스 확장하기 (
interface A extends B
)인터섹션 연산자 사용하기 (
type PersonWithBirthDate = Person & { birth: Date }
)인덱싱 사용하기 (
.. userId: State['userId'] ..
)
그 외에도 다양한 방법을 소개한다.
Pick
- 타입의 일부만 가져오기
Pick
- 타입의 일부만 가져오기매핑된 타입 사용하기 (
type TopNavState = { [k in 'userId' | 'pageTitle' | 'recentFiles']: State[k] }
)표준 라이브러리
type Pick<T, K> = { [k in K]: T[k] }
type TopNavState = Pick<State, 'userId' | 'pageTitle' | 'recentFiles'>
Partial
- 선택적으로 만들기
Partial
- 선택적으로 만들기✅ 이때 매핑된 타입과 keyof를 사용하면 Options로부터 OptionsUpdate를 만들 수 있다.
✅ 또는 표준 라이브러리 Partial을 사용할 수 있다.
typeof
- 값의 형태에 해당하는 타입 정의하기
typeof
- 값의 형태에 해당하는 타입 정의하기이런 경우 typeof를 쓰면 된다.
자바스크립트의 런타임 연산자 typeof를 사용한 것처럼 보이지만, 실제로는 타입스크립트 단계에서 연산되며, 훨씬 더 정확하게 타입을 표현한다.
주의사항도 있다. 이렇게 값으로부터 타입을 만들어 낼 때는 선언의 순서에 주의해야 한다. 타입 정의부터 먼저 하고 그 값이 그 타입에 할당이 가능하다고 선언하는 것이 좋다.
ReturnType - 함수나 메서드의 반환 값에 명명된 타입 만들기
이럴 땐 조건부 타입(Item 50)이 필요하다. 하지만 표준 라이브러리에는 이러한 일반적 패턴의 제너릭 타입이 정의되어 있다.
typeof
와 마찬가지로 이런 기법은 신중하게 사용해야 한다. 적용 대상이 값인지 타입인지 정확히 알고 구분해 처리해야 한다.
extends
- 제너릭에서 매개변수 제한하기
extends
- 제너릭에서 매개변수 제한하기extends
를 사용하면 <>
안에 들어가는 제너릭 매개변수가 특정 타입을 확장한다고 선언할 수 있다.
{ first: string }
은 Name
을 확장하지 않으므로 오류가 발생한다.
앞에 나온 Pick
의 정의는 extends
를 사용하여 완성할 수 있다. 타입 체커를 통해 기존 예제를 실행해보면 오류가 발생한다.
K
는 T
타입과 무관하고 범위가 너무 넓다. K
는 인덱스로 사용할 수 있는 string | number | symbol
이 되어야 하며, 실제로는 범위를 좀 더 좁힐 수 있다. K
는 실제로 T
의 키의 부분 집합, 즉 keyof T
가 되어야 한다.
Summary
DRY(Don't Repeat Yourself)
원칙을 타입에도 최대한 적용하자.타입에 이름을 붙여서 반복을 피하고,
extends
를 이용해 인터페이스 필드의 반복을 피하자.타입들 간의 매핑을 위해 타입스크립트가 제공한 도구들(
keyof
,typeof
, 인덱싱, 매핑된 타입 등)을 이용하자.제너릭 타입은 타입을 위한 함수와 같다. 타입을 반복하는 대신 제너릭 타입을 사용해 타입들 간 매핑을 사용하고, 제한하기 위해서
extends
를 사용하자.표준 라이브러리에 정의된
Pick
,Partial
,ReturnType
같은 제너릭 타입에 익숙해지자.
Last updated