You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 13:35:28