TypeScript中是否需同时传递泛型类型与枚举参数?
解决方案
一、简化MyTypes类型定义
原来的嵌套条件类型可以用映射类型替代,直接建立枚举值与对应类型的关联,代码更简洁易维护:
type Type1 = { num1: number; str1: string }; type Type2 = { num2: number; str2: string }; type Type3 = { num3: number; str3: string }; type Type4 = { num4: number; str4: string }; enum MyEnum { ONE, TWO, THREE, FOUR, } // 定义枚举到类型的映射表 type EnumTypeMap = { [MyEnum.ONE]: Type1; [MyEnum.TWO]: Type2; [MyEnum.THREE]: Type3; [MyEnum.FOUR]: Type4; }; // 替代原来的MyTypes<T> type MyTypes<T extends MyEnum> = EnumTypeMap[T];
二、优化myFun调用方式:仅传运行时参数,自动推导类型
TypeScript 可以根据传入的枚举参数自动推导泛型类型,完全不需要手动传递泛型参数。修改后的myFun核心逻辑不变,但调用时只需传一次枚举值:
const urls = { [MyEnum.ONE]: 'http://one.com', [MyEnum.TWO]: 'http://two.com', [MyEnum.THREE]: 'http://three.com', [MyEnum.FOUR]: 'http://four.com', }; const fetchData = (_url: string): unknown => ({ // ... 实际请求逻辑 }); export const myFun = <T extends MyEnum>(type: T) => { const data = fetchData(urls[type]); return { data: data as MyTypes<T> }; }; // 调用时仅传一次枚举值,TypeScript自动推导返回类型 const one = myFun(MyEnum.ONE); // one.data 类型为 Type1 const two = myFun(MyEnum.TWO); // two.data 类型为 Type2 const three = myFun(MyEnum.THREE); // three.data 类型为 Type3 const four = myFun(MyEnum.FOUR); // four.data 类型为 Type4
可选:支持仅传泛型的调用方式(不推荐,实用性低)
如果一定要实现myFun<MyEnum.ONE>()这种调用方式,由于TypeScript泛型在运行时会被擦除,需要额外维护一份枚举值的映射,通过泛型对应的键来获取运行时的枚举值。示例如下:
// 新增泛型到枚举值的映射(需与MyEnum保持同步) const EnumValueMap = { [MyEnum.ONE]: MyEnum.ONE, [MyEnum.TWO]: MyEnum.TWO, [MyEnum.THREE]: MyEnum.THREE, [MyEnum.FOUR]: MyEnum.FOUR, } as const; // 重载函数,支持两种调用方式 export function myFun<T extends MyEnum>(): { data: MyTypes<T> }; export function myFun<T extends MyEnum>(type: T): { data: MyTypes<T> }; export function myFun<T extends MyEnum>(type?: T) { const actualType = type ?? (EnumValueMap[T as keyof typeof EnumValueMap] as T); const data = fetchData(urls[actualType]); return { data: data as MyTypes<T> }; } // 两种调用方式都支持 const one = myFun<MyEnum.ONE>(); // 仅传泛型 const two = myFun(MyEnum.TWO); // 仅传参数
不过这种方式需要额外维护EnumValueMap,增加了维护成本,因此更推荐第一种仅传参数的方式。
内容的提问来源于stack exchange,提问作者sgmonda
相关产品推荐
相关产品推荐

