티스토리 뷰
🐰 유틸리티 타입
제네릭, 맵드 타입, 조건부 타입 등의 타입 조작 기능을 이용해 실무에서 자주 사용되는 타입을 미리 만들어 놓은 것
🐰 조건부 타입 기반의 유틸리티 타입
1. Exclude<T, U>
exclude
제거하다, 추방하다
T에서 U를 제거하는 유틸리티 타입
type A = Exclude<string | boolean, boolean>
// 타입 A는 string| boolean에서 boolean 타입을 제거한 타입
// => string 타입
타입 A는 string | boolean 타입에서 boolean 타입을 제거한 타입을 갖는다. 따라서 타입 A는 string 타입이 된다.
Exclude<T, U> 직접 구현하기
// Exclude 직접 구현하기
type Exclude<T, U> = T extends U? never : T;
// 타입 Exclude는 타입 변수 T, U를 받아 T가 U의 확장이라면 never, 아니면 T
타입 Exclude는 타입 변수 T, U를 받아와 T가 U를 확장한 타입이라면 never, 아니면 T를 그대로 가진다.
따라서 타입 A의 타입은 다음과 같은 과정을 거쳐 추론된다.
- 각 타입을 하나씩 대입
- Exclude<string, boolean> |
- Exclude<boolean, boolean>
- 각 결과 합치기
- string |
- never
- 최종 타입
- string <- never는 공집합이므로 합집합의 결과는 string
2. Extract<T, U>
extract
추출하다. 뽑아내다
T에서 U를 추출하는 유틸리티 타입
type B = Extract<string | boolean, boolean>;
// 타입 B는 string | boolean 에서 boolean 타입을 뽑아낸 타입
// -> boolean 타입
타입 B는 string | boolean 타입에서 boolean 타입을 추출한 타입이다. 따라서 타입 B는 boolean 타입이 된다.
Extract<T, U> 직접 구현하기
// Extract 직접 구현하기
type Extract<T, U> = T extends U? T : never;
// 타입 Extract는 타입 변수 T, U를 받아 T가 U의 확장이라면 T, 아니면 never
타입 Extract는 타입 변수 T, U를 받아와 T가 U를 확장한 타입이라면 T, 아니면 never를 타입으로 가진다.
따라서 타입 B의 타입은 다음과 같은 과정을 거쳐 추론된다.
- 각 타입을 하나씩 대입
- Extract<string, boolean> |
- Extract<boolean, boolean>
- 각 결과 합치기
- never |
- boolean
- 최종 타입
- boolean <- never는 공집합이므로 합집합의 결과는 boolean
3. ReturnType<T>
return
반환하다
함수의 반환값 타입을 추출하는 타입
function funcA(){
return 'hello';
};
function funcB(){
return 10;
};
type ReturnA = ReturnType<typeof funcA>;
// funcA의 반환값 타입은 string
// -> 타입 ReturnA는 string 타입
type ReturnB = ReturnType<typeof funcB>;
// funcB의 반환값 타입은 number
// -> 타입 ReturnB는 number 타입
ReturnType은 함수의 반환값 타입을 타입 변수 T에 받아와 타입을 추론한다.
타입 ReturnA는 funcA의 반환값 타입을 타입변수 T로 넘긴다. 따라서 ReturnA는 string 타입이 된다.
타입 ReturnB는 funcB의 반환값 타입을 타입변수 T로 넘긴다. 따라서 ReturnB는 number 타입이 된다.
ReturnType<T> 직접 구현하기
// ReturnType 직접 구현하기
type ReturnType<T extends (...arg: any)=> any> = T extends (
...arg: any
) => infer R ? R : never;
// T에는 함수 타입만 들어올 수 있음
// 매개변수 타입은 any로 설정
// 반환값 타입은 추론해야함 -> infer 사용
// R로 추론했을 때 참인경우 R, 거짓인 경우 never
ReturnType은 타입변수 T에 할당된 함수 타입의 반환값 타입을 추출하기 때문에 T는 함수 타입을 확장한 타입이다.
매개변수는 들어올 수도, 안들어올 수도 있기 때문에 any 타입으로 정의한다.
반환값 타입을 추론해야하기 때문에 infer을 써 R로 추론했을 때 참인 경우 R을, 거짓인 경우 never를 타입으로 갖게 된다.
타입 RetrunA의 타입 추론 과정은 다음과 같다.
- 타입변수에 반환값 타입 전달
- funcA의 반환값 타입은 string
- => T에는 string 타입이 담김
- T가 R의 서브타입이 되도록 추론
- string이 R의 서브타입이 되어야 함
- => R은 string 타입