프로그래밍/typescsript
타입스크립트의 Mapped Type(맵드 타입)
한코코
2022. 11. 23. 14:53
타입스크립트에서 map처럼 타입을 각각 변환하는 방법이며 아래와 같은 형태의 문법을 사용해야 한다.
{ [ P in K ] : T }
{ [ P in K ] ? : T }
{ readonly [ P in K ] : T }
{ readonly [ P in K ] ? : T }
기본 예제
히어로들의 이름에 각각 나이까지 붙인 객체를 만들고 싶다면 아래와 같이 코드를 사용하면 된다.
type Heroes = 'Hulk' | 'Thor' | 'Capt';
// for in 문법과 유사한 K in Heroes
type HeroProfiles = { [K in Heroes]: number };
const heroInfo: HeroProfiles = {
Hulk: 54,
Thor: 1000,
Capt: 33,
}
위 코드에서 [K in Heroes] 부분은 마치 자바스크립트의 for in 문법과 유사하게 동작한다.
앞에서 정의한 Heroes 타입의 3개의 문자열을 각각 순회하여 number 타입을 값으로 가지는 객체의 키로 정의가 된다.
{ Hulk: number } // 첫번째 순회
{ Thor: number } // 두번째 순회
{ Capt: number } // 세번째 순회
따라서 위의 원리가 적용된 HeroProfiles의 타입은 다음과 같다.
type HeroProfiles = {
Hulk: number;
Thor: number;
Capt: number;
}
실용 예제 1
다음은 실질적으로 자주 사용하게되는 코드다.
이 문법은 키와 값이 있는 객체를 정의하는 타입을 받아 그 객체의 부분 집합을 만족하는 타입으로 변환해준다.
type Subset<T> = {
[K in keyof T]?: T[K];
}
위 문법을 사용하면 다음과 같은 객체를 모두 정의할 수 있다.
interface Person {
age: number;
name: string;
}
const ageOnly: Subset<Person> = { age: 23 };
const nameOnly: Subset<Person> = { name: 'Tony' };
const ironman: Subset<Person> = { age: 23, name: 'Tony' };
const empty: Subset<Person> = {};
실용 예제 2
interface UserProfile {
username: string;
email: string;
profilePhotoUrl: string;
}
interface UserProfileUpdate {
username?: string;
email?: string;
profilePhotoUrl?: string;
}
동일한 타입에 대해서 반복해서 선언하는 것을 피하기 위해 아래 코드처럼 정리할 수 있다.
type UserProfileUpdate = {
username?: UserProfile['username'];
email?: UserProfile['email'];
profilePhotoUrl?: UserProfile['profilePhotoUrl'];
}
// 좀더 줄여보기
type UserProfileUpdate = {
[p in 'username' | 'email' | 'profilePhotoUrl']?: UserProfile[p]
}
// keyof를 사용해 좀더 줄여보기
type UserProfileUpdate = {
[p in keyof UserProfile]?: UserProfile[p]
}
참고 사이트 : 공식 타입스크립트 핸드북