如何在基于映射函数参数推导类型的函数中避免类型转换?
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
相关产品推荐
相关产品推荐

