如何在TypeScript中从函数对象推断equals函数的参数类型
问题
我有如下对象:
{ num1: 1, num2: 2, str: "abc" }
想要创建一个泛型函数fn,第一个参数接收任意此类结构的对象,第二个参数接收自定义选择器对象。原函数定义如下:
function fn<O extends object, S extends object>( obj: O, selectors: { [K in keyof S]: { selector: (obj: O) => InferReturnType; equals: (a: InferReturnType, b: InferReturnType) => boolean; } } ) { }
我希望每个选择器中的equals函数参数a、b能自动推断为对应selector函数的返回类型。比如调用时:
fn( { num1: 1, num2: 2, str: "abc" }, { selector1: { selector: ({ num1, num2 }) => ({ num1, num2 }), equals: (a, b) => a.num1 === b.num1 && a.num2 === b.num2, }, selector2: { selector: ({ num1, str }) => ({ num1, str }), equals: (a, b) => a.num1 === b.num1 && a.str === b.str, } } )
这里selector1的equals参数应自动识别为包含num1和num2的对象类型,selector2的参数自动识别为包含num1和str的对象类型。
解决方案
调整泛型参数定义,让每个选择器的返回类型作为泛型的一部分被TypeScript自动推断。修改后的函数定义如下:
function fn<O extends object, S extends Record<string, unknown>>( obj: O, selectors: { [K in keyof S]: { selector: (obj: O) => S[K]; equals: (a: S[K], b: S[K]) => boolean; }; } ) { // 函数逻辑可在此实现 }
原理说明
- 泛型
O代表输入对象的类型,S代表所有选择器返回类型的集合,每个键对应一个选择器的返回值类型。 - 通过映射类型
[K in keyof S],将每个选择器的selector返回类型绑定到S[K],同时让equals函数的参数类型与该返回类型保持一致。 - TypeScript会自动根据每个
selector函数的返回值推断出S中对应键的类型,从而让equals的参数获得准确的类型提示。
调用示例
使用修改后的函数,调用时TypeScript会自动完成类型推断:
fn( { num1: 1, num2: 2, str: "abc" }, { selector1: { selector: ({ num1, num2 }) => ({ num1, num2 }), equals: (a, b) => a.num1 === b.num1 && a.num2 === b.num2, // a、b类型为{ num1: number; num2: number } }, selector2: { selector: ({ num1, str }) => ({ num1, str }), equals: (a, b) => a.num1 === b.num1 && a.str === b.str, // a、b类型为{ num1: number; str: string } } } )
内容的提问来源于stack exchange,提问作者y627chen
相关产品推荐
相关产品推荐

