타입스크립트에서 다양한 상황에서 활용되는 extends
T extends U ? X : Y
// 타입 T를 U에 할당할 수 있으면 X 타입
// 타입 T를 U에 할당할 수 없으면 Y 타입
interface Bank {
financialCode: string;
fullName: string; // Card와의 차이
}
interface Card {
financialCode: string;
appCardType?: string; // Bank와의 차이
}
type payMethod<T> = T extends "card" ? Card : Bank; // 제네릭 타입으로 extends를 사용한 조건부 타입
type CardPayMethodType = PayMethod<"card">; // 제네릭 매개변수 = "card" : Card 타입
type BankPayMethodType = PayMethod<"bank">; // 제네릭 매개변수 != "card" : Bank 타입
그리고 react-query를 사용한 커스텀 훅
type PayMethodType = PayMethodInfo<Card> | PayMethodInfo<Bank>;
// 인자의 type을 통해 알맞은 타입의 결과를 리턴하고싶다.
export const useGetRegisteredList = (
type: 'card' | 'appcard' | 'bank'
): useQueryResult<PayMethodType[]> => {
const url = `baeminpay/code/${type === 'appcard' ? 'card' : type}`;
const fetcher = fetcherFactory<PayMethodType[]>({
onSuccess: (res) => {
const usablePockerList = res?.filter(
(pocker: PocketInfo<Card> | PocketInfo<Bank>) => pocket?.useType === 'USE'
) ?? [];
return usablePockerList;
}
});
const result = useCommonQuery<PayMethodType[]>(url, undefined, fetcher);
return result;
}
CardBank 이렇게 원했을텐데PayMethodType을 Card 또는 Bank 타입의 PatMethodInfo 중 하나로 고정하고 반환값 result에 PayMethodType[] 타입을 명시해주었다. 하지만 Card와 Bank 를 명확히 구분하는 로직이 없다— 개선
// before
type PayMethodType = PayMethodInfo<Card> | PayMethodInfo<Bank>;
// after
type PayMethodType<T extends "card" | "appcard" | "bank"> = T extends
| "card"
| "appcard"
? Card
: Bank;
// PayMethodType의 제네릭으로 받은 값이 "card" 또는 "appcard"면 PayMethodInfo<Card> 타입을 반환
// PayMethodType의 제네릭으로 받은 값이 이외의 값이면 PayMethodInfo<Bank> 타입을 반환
// T extends ("card" | "appcard") ? Card : Bank;