일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 실행컨텍스트
- 자바스크립트
- Arrow function
- 함수
- moment.js
- JavaScript
- variable object
- function 문
- 함수 표현식
- vs code
- function 표현식
- react router
- scope chain
- hoisting
- happy hacking
- BIND
- 호이스팅
- type
- This
- lexical environment
- function
- 화살표 함수
- react-router
- Execution Context
- activation object
- 리액트 라우터
- lexical scope
- 정적스코프
- 객체
- webstorm
- Today
- Total
Pandaman Blog
[Typescript] Mapped Types 본문
Utility 타입에 대한 궁금증에 내부 코드를 보았고, 내부 코드를 보는 순간 아 잘 모르겠다. 라는 생각으로 Mapped types 이란 것을 공부하기로 했다.
Mapped Types
자바스크립트에서 map
메서드는 배열 내의 모든 요소 각각에 대해 순회하며 새로운 배열을 반환한다.
['1', '2', '3'].map(value => Number(value)); // [1, 2, 3]
map
메서드를 통해서 각 문자열을 숫자로 맵핑하여 새로운 배열을 반환했다. 타입스크립트의 mapped type도 위와 마찬가지로 타입을 순회하며 새로운 타입으로 변환하는것을 의미한다.
index signature
인덱스 시그니처는 타입의 속성 이름을 잘 모르지만 값의 타입을 알 경우 사용된다.
type Person = {
[key: string]: string;
}
const person: Person = {
job: 'developer',
name: 'coo',
}
Keyof 연산자
keyof 연산자는 무엇일까? 공식문에서는 객체 타입의 속성을 string, number, 리터럴 유니온 타입으로 만들어 준다.
바로 아래처럼 말이다.
type Person = {
name: string;
age: number;
}
type Keys = keyof Person
// type Keys = 'name' | 'age';
예제를 살펴보자.
링크
keyof 연산자를 통해서 타입의 property만 추출했다. keyof 연산자는 mapped type 에서 매우 유용하게 사용될 수 있다.
union type 을 사용한 mapped type
type Person = {
name: string;
age: number;
job: string;
};
type PersonOnlyString = { [K in keyof Person]: string; };
// type PersonOnlyString = {
// name: string;
// age: string;
// job: string;
// }
대괄호([ ]
) 내부에 K in keyof Person
로 작성되어 있는데, in
뒤의 타입(keyof Person
)은 꼭 유니온 타입이여야 한다. in
앞에 K
타입은 유니온 타입중 하나이다. 그리고 순회하며(K: string
) 새로운 타입을 반환하는 것이다.
as 를 사용한 key remapping
값의 타입을 맵핑하는 방법도 있지만 as 절을 사용해 속성를 Remapping 하는 방법도 존재한다.
링크
type Person = {
name: string;
age: number;
job: string;
};
type HandlerPersonTypes = {
[K in keyof Person as `handle${Capitalize<K>}`]: () => void;
}
K in keyof Person
이후 as
절을 사용하여 속성을 handle${Capitalize<K>}
로 재맵핑 했다. 그리고 각 속성은 () => void
타입을 갖도록 했다. 결론적으로 해당 Mapped type은 아래와 같다.
type HandlerPersonTypes = {
handleName: () => void;
handleAge: () => void;
handleJob: () => void;
}
사실 언제 사용될지는 잘 모르겠지만...너무 신기하면서 재밌다.
Generic을 사용한 Mapped type
또 다른 예제이다. 모든 객체타입에 대해 옵션널 타입으로 변경해주는 타입을 만들고 싶을때가 있다.
링크
type BeforeType = {
name: string;
key: string;
unit: string;
}
type OptionalType = {
name?: string;
key?: string;
unit?: string;
};
위의 예제는 객체 타입의 속성을 모두 Optional 하게 변경한것이다. 이것을 Mapped type을 활용해서 변경할 수 있는 방법이 없을까?
우리에겐 제네릭이 있다.
type Optional<T> = { [K in keyof T]?: T[K] };
// 공통으로 사용할 수 있다.
type OptionalType = Optional<BeforeType>;
- 제네릭(
<T>
) 을 통해 타입인자 T를 받는다. keyof
연산자를 통해 T의 속성으로 이루어진 유니온 타입을 만든다.- in 키워드를 통해
K?: T[K]
를 순회하여 각 속성에 대해 옵션널한 새로운 타입을 반환한다. - T[K] 는 객체 타입(T)에서 특정 속성(K)로 접근한것이다. 즉 특정속성의 타입을 말한다.
예) BeforType['name'], BeforeType['key'], ...
지금까지 여러방법으로 Mapped 타입을 사용해보았는데, 이보다 더 다양한 방법으로 Mapped 타입을 유용하게 사용할 수 있을 것이다.
'Front end > Typescript' 카테고리의 다른 글
[Typescript] Utility Types - 2 (0) | 2022.03.27 |
---|---|
[Typescript] Conditional Types (0) | 2022.03.13 |
[Typescript] Utility Types - 1 (0) | 2022.02.21 |
[Typescript] 함수 (0) | 2021.12.19 |
[Typescript] Type Guard (0) | 2021.12.18 |