유틸리티 타입
이미 정의해 놓은 타입을 변환할 때 사용하기 좋은 문법이다. 꼭 이것을 사용하지 않더라도 인터페이스나 제네릭으로 타입을 변환할 수 있지만 유틸리티 타입을 사용함으로 인해 더 간결하게 정의할 수 있다.
Pick
예를들어 어떠한 상품들의 목록이 있고, 그 상품의 상세 내용을 보는 페이지가 있다고 가정해 보자.
interface Product {
id: number;
name: string;
price: number;
brand: string;
stock: number;
}
// 상품 목록 받아오는 API 함수
function fetchProducts(): Promise<Product[]> {
//..
}
// Product의 일부 속성
interface ProductDetail {
id: number;
name: string;
price: number;
}
// 상품의 상세내용 조회
function displayProductDetail(shoppingItem: ProductDetail) {
//..
}
상품의 목록의 인터페이스 Product가 있고, 각 상품의 상세내용 인터페이스 ProductDetail이 있다. 상품의 상세내용을 조회하기 위해선 Product 인터페이스의 일부 속성이 필요하기 때문에 그것들을 사용하여 ProductDetail 인터페이스를 정의했다. 하지만 그만큼 중복코드가 생겨버린다.
// 상품의 상세내용 조회
type ShoppingItem = Pick<Product, 'id' | 'name' | 'price'>;
function displayProductDetail(shoppingItem: ShoppingItem) {
//..
}
이 때 사용하는 것이 바로 Pick 이다. Pick은 기존에 존재하는 타입에서 자신이 원하는 속성으로 별도의 타입을 만들수 있다.
Omit
Omit은 Pick과 상반되는 기능을 한다고 볼 수 있다.
Pick은 기존에 존재하는 타입에서 자신이 사용하고자 하는 속성만을 말 그대로 pick 해서 만드는 것이고, Omit 또한 말 그대로 기존에 존재하는 타입에서 지정된 속성만 제거한 타입을 정의한다.
interface Address {
name: string;
phone: number;
address: string;
company: string;
}
type Phone = Omit<Address, 'address'>;
const phoneBook: Phone = {
name: '이름',
phone: 1234,
company: '회사',
};
type Food = Omit<Address, 'address' | 'company'>;
const kimbabHeaven: Food = {
name: '김밥천국',
phone: 5678,
};
Partial
Partial은 기존에 존재하는 타입의 부분 집합을 만족하는 타입을 정의할 수 있다.
위에서 설명했던 Product 코드에 이어서 설명하자면,
interface Product {
id: number;
name: string;
price: number;
brand: string;
stock: number;
}
// ... 중략
interface UpdateProduct {
id?: number;
name?: string;
price?: number;
brand?: string;
stock?: number;
}
// 상품 정보를 업데이트하는 함수
function updateProductItem(productItem: UpdateProduct) {}
어떠한 상품 정보를 업데이트하고자 할때 상황마다 업데이트 해야할 속성값들이 매번 다를 수 있으므로 모든 속성들에 대해 옵셔널 옵션( ? )을 줄 수도 있다.
하지만 이미 Product 인터페이스가 있음에도 불구하고 중복으로 UpdateProduct 인터페이스를 정의 해야 했다. 이 때 사용할 수 있는게 바로 Partial 이다.
type UpdateProduct = Partial<Product>
function updateProductItem(productItem: UpdateProduct) {}
이렇게만 해주면 위에 옵셔널 속성을 사용한 UpdateProduct와 동일한 효과를 나타낸다.
Partial 구현해보기
interface UserProfile {
username: string;
email: string;
profilePhotoUrl: string;
}
// 첫 번째 축약방법
type UserProfileUpdate = {
username?: UserProfile['username'];
email?: UserProfile['email'];
profilePhotoUrl?: UserProfile['profilePhotoUrl'];
};
// 두 번째 축약방법
// p 변수에 username, email, profilePhotoUrl이 각각 반복문을 돌며 할당된다.
type UserProfileUpdate = {
[p in 'username' | 'email' | 'profilePhotoUrl']?: UserProfile[p];
};
// 세 번째 축약방법
// keyof를 사용하여 더 간단하게 줄일 수 있다.
type UserProfileUpdate = {
[p in keyof UserProfile]?: UserProfile[p];
};
// 실제 partial의 구조
type Subset<T> = {
[p in keyof T]?: T[p];
};
Mapped Type
맵드 타입이란 기존에 정의되어 있는 타입을 새로운 타입으로 변환해주는 문법이다. (자바스크립트 es6의 map 함수와 비슷)
type Foods = 'ForkCutlet' | 'Hamburger' | 'Pizza'
type FoodPrices = { [K in Foods]: number }
이렇게 할 경우 FoodsPrices 타입은 아래와 같이 된다.
type FoodPrices = {
ForkCutlet: number;
Hamburger: number;
Pizza: number;
}
'Javascript' 카테고리의 다른 글
[클린코드 자바스크립트] 임시변수 제거하기 (0) | 2021.11.11 |
---|---|
자바스크립트 Event Loop (0) | 2021.06.02 |
타입스크립트 - 타입 가드 (0) | 2021.04.12 |
타입스크립트 - 타입 추론 & 단언 (0) | 2021.04.12 |
타입스크립트 - 제네릭 (0) | 2021.04.08 |
댓글