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

如何在基于映射函数参数推导类型的函数中避免类型转换?

TypeScript动态类型安全函数类型错误解决办法

问题原因

你遇到的类型错误源于TypeScript编译器无法在泛型函数中自动关联testing[value.type]的参数类型与value.value的类型。虽然逻辑上两者完全匹配,但编译器会将x的参数类型推断为number & string(即never),而value.value的类型是string | number,因此触发类型不兼容报错。


解决方案一:区分联合类型 + Switch Case

这种方式利用TypeScript的类型窄化特性,让编译器自动识别每个分支的类型,无需任何类型断言,是最安全的实现方式。

首先修正枚举的语法错误(原枚举误用冒号,应改为等号),然后定义区分联合类型作为函数参数:

// 修正枚举语法
enum FunctionNames {
  printNumber = "printNumber",
  printString = "printString"
}

// 映射对象
const testing = {
  [FunctionNames.printNumber]: (number: number) => {
    console.log(number);
  },
  [FunctionNames.printString]: (string: string) => {
    console.log(string);
  },
};

// 生成区分联合类型:自动关联type与对应的value类型
type WrapperArgs = {
  [K in keyof typeof testing]: { type: K; value: Parameters<typeof testing[K]>[0] }
}[keyof typeof testing];

// 包装函数
const testWrapper = (value: WrapperArgs) => {
  switch (value.type) {
    case FunctionNames.printNumber:
      testing[value.type](value.value); // 类型自动匹配,无错误
      break;
    case FunctionNames.printString:
      testing[value.type](value.value);
      break;
  }
};

解决方案二:泛型函数中添加安全类型断言

如果需要保留泛型写法,可以添加基于类型关联的安全断言(而非强制转换为never),让编译器认可类型匹配:

enum FunctionNames {
  printNumber = "printNumber",
  printString = "printString"
}

const testing = {
  [FunctionNames.printNumber]: (number: number) => {
    console.log(number);
  },
  [FunctionNames.printString]: (string: string) => {
    console.log(string);
  },
};

type UpdateValue<T extends keyof typeof testing> = Parameters<typeof testing[T]>;

const testWrapper = <T extends keyof typeof testing>(value: { type: T; value: UpdateValue<T>[0] }) => {
  const x = testing[value.type];
  // 断言参数符合当前泛型对应的函数参数类型,逻辑上完全安全
  x(value.value as Parameters<typeof testing[T]>[0]);
};

内容的提问来源于stack exchange,提问作者stonefarmer9

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 05:28:13