type SomeType<T extends "A">
=> type 선언부의 Generic 을 "A" 타입으로 사용하겠다.
type SomeType<T> = T extends "A" ? string : never;
=> SomeType 에 받은 Generic 이, "A" 라는 조건을 만족하면 string type, 아니라면 에러를 반환하겠다.
이 두가지와 Enum 을 활용해서 아래와 같이
Enum에 따라서 타입 추론이 되는 함수를 만들어 활용할 수 있다.
type UserData = {
name: string;
age: number;
gender: "male" | "female";
};
type CartData = {
items: Array<CartItem>;
total: number;
tax: number;
};
type CartItem = {
title: string;
amount: number;
price: number;
discountedPrice: number;
};
type PurchaseData = {
purchases: Array<PurchaseItem>;
};
type PurchaseItem = {
title: string;
price: number;
refunded: boolean;
};
enum API_TYPES {
USER = "user",
CART = "cart",
PURCHASE = "purchase"
}
type ApiDataMap =
| {
type: API_TYPES.USER;
data: UserData;
}
| {
type: API_TYPES.CART;
data: CartData;
}
| {
type: API_TYPES.PURCHASE;
data: PurchaseData;
};
type ExtractDataType<Type extends API_TYPES, DataType> = DataType extends { type: Type; data: ApiDataMap["data"] }
? DataType["data"]
: never;
const fetchItem = <T extends API_TYPES>(type: T): ExtractDataType<T, ApiDataMap> => {
switch (type) {
case API_TYPES.USER:
return {
name: "user",
age: 19,
gender: "male"
} as any;
case API_TYPES.CART:
return {
total: 0,
tax: 0,
items: []
} as any;
case API_TYPES.PURCHASE:
return {
purchases: []
} as any;
default:
return null as any;
}
};
const updateItem = <T extends API_TYPES>(type: T, item: Partial<ExtractDataType<T, ApiDataMap>>) => {
// update logic
};
updateItem(API_TYPES.USER, { name: "bang9" });
updateItem(API_TYPES.CART, { name: "bang9" }); // Error
const userItem = fetchItem(API_TYPES.USER);
const cartItem = fetchItem(API_TYPES.CART);
const purchaseItem = fetchItem(API_TYPES.PURCHASE);
케이스가 좀 더 필요하다면 아래의 글도 참조하시라
https://velog.io/@bang9dev/Typescript-generic-with-function-logic
감사합니다!