TypeScript如何定义泛型函数实现参数类型映射与键值类型自动推导
问题原因
原写法不生效的核心是 TypeScript 不支持部分泛型参数推断:当你显式指定第一个泛型参数T = TestType时,第二个泛型参数K因为设置了默认值keyof T,TS 会直接使用这个默认的联合类型'something' | 'other',不会再根据实际传入的第一个入参key动态推断K的具体字面量类型,最终导致arg的类型被推导为string | number,无法和key做绑定映射。
可行解决方案
方案1:柯里化拆分泛型(全TS版本兼容,类型最严谨)
将接收类型参数、接收入参的逻辑拆成两层函数,第一层固定传入目标类型T,返回的第二层函数单独做K的类型推断,绕开部分泛型推断的限制。
interface TestType { something: string; other: number; } function func<T>() { return function <K extends keyof T>(key: K, arg: T[K]) { // 业务逻辑 } } // 调用示例 const testFunc = func<TestType>(); testFunc('something', '字符串参数') // 第二个参数自动推导为string,传数字会报错 testFunc('other', 123) // 第二个参数自动推导为number,传字符串会报错 // key参数会自动补全something/other,传入非法值直接报类型错误
- 优点:类型映射完全符合预期,自动补全、类型校验都正常,兼容所有TS版本
- 缺点:需要先调用一次拿到绑定类型的函数,无法直接写成
func<TestType>(key, arg)的单调用形式
方案2:通过入参锚定类型(无需柯里化)
如果不想改动调用层级,可以给函数加一个类型锚点入参,不需要显式传入泛型参数,TS会通过锚点自动识别目标类型T,同时正常推断K的类型。
interface TestType { something: string; other: number; } function func<T, K extends keyof T = keyof T>( _anchor: T, key: K, arg: T[K] ) { // 业务逻辑 } // 调用示例:第一个参数传类型断言的空对象作为锚点即可,无实际业务含义 func({} as TestType, 'something', '字符串参数') func({} as TestType, 'other', 123)
- 优点:保持单函数调用形式,类型校验、自动补全正常
- 缺点:需要多传一个无实际业务意义的类型锚点参数
注:目前TS没有原生支持
func<TestType>(key, arg)这种单调用、部分显式传泛型的写法,相关的部分泛型参数推断特性还在提案阶段,未正式实装。
内容的提问来源于stack exchange,提问作者Sky
相关产品推荐
相关产品推荐

