고급 타입인 'utility type' 몇가지를 살펴보자.
이미 정의해 놓은 타입을 변환할 때 사용하기 좋은 문법이다. 기존의 인터페이스, 제네릭 등의 기본 문법으로 충분히 타입을 변환할 수 있지만 유틸리티 타입을 사용하면 훨씬 간결한 문법을 타입을 정의할 수 있다.
// 1) interface를 사용한 경우
interface Product {
id: number;
name: string;
price: number;
brand: string;
stock: number;
}
//Product 중에 id, name, price만 가져온 interface
interface ProductDetail {
id: number;
name: string;
price: number;
}
//product에 일부 속성만 필요한 경우
function displayProductDetail(shoppingItem: ProductDetail);
위의 코드에서 알 수 있듯이 Product 인터페이스의 속성들이 ProductDetail 인터페이스도 중복된다. 점점 중복된 코드들이 많아져서 가독성이 나빠진다.
// 2) utility 사용한 경우
type ShoppingItem = Pick<Product, 'id'|'name'|"price">
function displayProductDetail(shoppingItem: ShoppingItem) {}
pick을 이용해서 기존에 타입에서 원하는 속성만 반환할 수 있다. 불필요하게 새로운 interface를 만들 필요가 없다.
interface AddressBook {
name: string;
phone: number;
address: string;
company: string;
}
const phoneBook: Omit<AddressBook, 'address'> = {
name: '재택근무',
phone: 12342223333,
company: '내 방'
}
const chingtao: Omit<AddressBook, 'address'|'company'> = {
name: '중국집',
phone: 44455557777
}
interface Product {
id: number;
name: string;
price: number;
brand: string;
stock: number;
}
// 1) '옵셔널 태그'
interface UpdateProduct {
id?: number;
name?: string;
price?: number;
brand?: string;
stock?: number;
}
// 'Product' 에서 특정 상품 정보(필요한 것만)를 업데이트하는 함수
function updateProductItem(productItem: UpdateProduct) {
...
}
'Product' 인터페이스에서 필요한 정보만 골라서 업데이트하고 싶은 경우에 위 코드처럼 또 다른 인터페이스에 옵셔널 태그를 작성하여 만들어줄 수 있다. 하지만 가독성이 떨어진다.
// 2) 'partial'
type UpdateProduct = Partial<Product>
function updateProductItem(productItem: Partial<Product>) {...
}
'partial'을 사용하여 원하는 속성만 골라 쓸 수 있다.
interface UserProfil {
username: string;
email: string;
profilImgUrl: string;
}
// 프로필 사진이나 닉네임을 바꿀 경우 - 또 다른 interface를 만들어서 구현하기
interface UserProfilUpdate {
username?: string;
email?: string;
profilImgUrl?: string;
}
// 1.별도의 interface를 만들지 않고 기존의 인터페이스 재활용하기 - 속성타입을 인덱스로 접근
type UserProfilUpdate = {
username?: UserProfil['username'];
email?: UserProfil['email'];
profilImgUrl?: UserProfil['profilImgUrl'];
}
// 2.mapped type - 속성들을 반복문 돌려서 접근
type UserProfilUpdate = {
[p in 'username' | 'email' | 'profilImgUrl']?: UserProfil[p]
}
type UserProfilKeys = keyof UserProfil
// 3. union 타입을 keyof를 이용해 축약
type UserProfilUpdate = {
[p in keyof UserProfil]?: UserProfil[p]
}
// 4. 최종 partial 구현
type Subset<T> = {
[p in keyof T]?: T[p]
}
기존에 정의되어 있는 타입을 새로운 타입으로 변환해 주는 문법을 말한다. 타입에 map함수를 돌려서 새로운 타입을 반환한다고 생각하면 편하다.
{ [ P in K ] : T }
{ [ P in K ] ? : T }
{ readonly [ P in K ] : T }
{ readonly [ P in K ] ? : T }
type Heros = 'Hulk' | 'Capt' | 'Thor'
// 일반 타입 변수 'K'
type HeroAges = {[K in Heros]:number }
const ages: HeroAges = {
Hulk: 33,
Capt: 100,
Thor: 1000
}