유틸리티 타입은 필수 개념은 아니나, 후에 코드 유지보수성을 높여줄 수 있는 하나의 방법 중 하나입니다.
다음은 대표적인 유틸리티 타입 3가지 입니다.
선언한 타입들 중 일부만 사용하고 싶을때 사용합니다.
Usage : Pick<대상 type, '사용할 타입 나열~' | ' '>
interface Product {
id: number;
name: string;
price: number;
brand: string;
stock: number;
}
// 1. 상품 목록을 받아오기 위한 API 함수
function fetchProducts(): Promise<Product[]> {
//...
}
// interface ProductDetail {
// id: number;
// name: string;
// price: number;
// }
// 2. 특정 상품의 상세 정보를 나타내기 위한 함수
function displayProductDetail(shoppingItem: Pick<Product, 'id' | 'name' | 'price'>) {
}
shoppingItem
은 Product 중 id, name, price만 사용하고 싶을때 다음과 같이 Pick
예약어를 통해 일부만 가져다 쓸 수 있습니다.
이는 주석처리된 ProductDetail 인터페이스와 같은 작동방식을 지니며, 반복해서 쓸 필요없이 유지보수를 높여줍니다.
쓰지 않을 타입은 제외하고 나머지 타입들은 쓰겠다는 의도일때 사용합니다.
Usage : Omit<대상 type, '안 쓸 타입 나열~' | ' '>
선언된 타입들 중에서 일부의 상태값을 변화시키고 싶을때 주로 사용
Usage : Partial<type명>
interface UpdateProduct {
id?: number;
name?: string;
price?: number;
brand?: string;
stock?: number;
}
// 3. 특정 상품 정보를 업데이트하는 함수 (UpdateProduct와 같은 매커니즘)
function updateProductItem(productItem: Partial<Product>) {
}
?:
구문 활용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]
}
변수 p가 userProfile
인터페이스의 key값에 해당하는 부분을 반복문으로 돌며, 리턴 타입으로 value를 반환합니다.
type userProfileKeys = {
[p in keyof userProfile]?: userProfile[p]
}
3번 mapped type에서 유니온으로 선언된 key값들의 코드가 길어짐에 따라, keyof
예약어를 통해 코드를 간결하게 만들 수 있습니다.
결국 4번을 한번 더 리팩토링 시,
type Subset<T> = { [p in keyof T]?: T[p] }
제네릭 타입으로 다양한 인터페이스를 받아오고 이는 곧
Partial
이 TS에서의 모듈화된 코드입니다.
+) Mapped type
type Heroes = 'Hulk' | 'Capt' | 'BlackWidow'
type HeroAges = { [H in Heroes]: number }
const ages: HeroAges = {
Hulk : 33,
Capt : 100,
BlackWidow : '33' //리턴타입이 number가 아니므로 error code
}
mapped type은 map함수와 비슷한 맥락에서, 반복문을 돌면서 각각의 값들의 타입을 전체 반영해준다는 의미로 이해할 수 있습니다.