如何让TypeScript正确推断Test类型中transformer的参数类型?
TypeScript 实现基于 inputType 的 transformer 参数类型自动推断
问题背景
用户定义了以下TypeScript类型与辅助函数:
interface Test<R, T> { inputType: R; transformer: (input: R extends any ? R : never) => T; } // simple inference helper function function inferTest<T extends Test<any, any>>(t: T): T { return t; }
尝试按如下方式使用时:
const test = inferTest({ inputType: 0, transformer: input => String(input) })
理想状态下transformer应被推断为(input: number) => string,但实际input被推断为any,需要在不手动指定input类型的前提下实现正确的类型推断(真实场景中inputType的类型更为复杂)。
解决方案
问题核心在于原函数的泛型约束逻辑无法让TypeScript建立inputType与transformer参数类型的关联。通过直接将R和T设为函数的泛型参数,而非用T extends Test<any, any>的约束方式,即可解决该问题:
修正后的代码
interface Test<R, T> { inputType: R; transformer: (input: R) => T; } function inferTest<R, T>(t: Test<R, T>): Test<R, T> { return t; }
验证效果
使用修正后的代码,示例中的test会被正确推断:
test.inputType的类型为numbertest.transformer的类型为(input: number) => string
原理说明
原inferTest函数的泛型约束T extends Test<any, any>会让TypeScript先整体推断T的类型,此时transformer的参数类型无法与inputType的类型形成关联。而直接将R和T作为函数的泛型参数后,TypeScript会先从inputType的值推断出R的具体类型,再根据transformer的返回值推断出T,从而自动建立两者的类型关联,即使inputType是复杂类型也能正常工作。
内容的提问来源于stack exchange,提问作者Lehks
相关产品推荐
相关产品推荐

