如何获取仅含函数的类型中函数的参数类型?T2未被识别为函数的原因
问题分析与解决方案
你的代码已经通过OnlyFuncs<T>成功过滤了接口中的非函数成员,但编译器无法自动识别T2是函数类型,核心原因是:虽然Tfunc的所有成员都是函数,但在call方法的泛型定义中,T2 = Tfunc[K]只是类型赋值,没有显式告诉编译器T2必须是函数类型。TypeScript需要明确的类型约束才能确定Parameters<T2>的合法性。
解决方案一:直接使用Tfunc[K]获取参数类型
去掉多余的T2泛型参数,直接用Tfunc[K]作为Parameters的入参。因为OnlyFuncs<T>已经确保Tfunc[K]必然是函数类型,编译器可以直接识别:
interface MyApi { add(x: number, y: number): number; say(s: string): string; A: number; } type OnlyFuncs<T> = Pick<T, { [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never }[keyof T]>; class ApiClient<T, Tfunc = OnlyFuncs<T>> { public call<K extends keyof Tfunc>(method: K, p: Parameters<Tfunc[K]>) { // 这里可以实现实际调用逻辑 } } // 测试验证 const client = new ApiClient<MyApi>(); client.call('add', [1, 2]); // 参数类型匹配number[],符合预期 client.call('say', ['hello']); // 参数类型匹配string[],符合预期 // client.call('A', []); // 编译报错,已成功过滤非函数成员
解决方案二:为T2添加函数类型约束
如果需要保留T2泛型参数,只需给它加上明确的函数类型约束,让编译器确认T2是函数:
class ApiClient<T, Tfunc = OnlyFuncs<T>> { public call<K extends keyof Tfunc, T2 extends (...args: any[]) => any = Tfunc[K]>(method: K, p: Parameters<T2>) { // 实现逻辑 } }
原理说明
OnlyFuncs<T>通过映射类型筛选出T中所有值为函数类型的键,再用Pick提取对应成员,因此Tfunc的所有属性必然是函数。但TypeScript的泛型推断不会自动反向推导T2的类型特性,必须通过显式约束或直接使用Tfunc[K],才能让编译器确认类型兼容性。
内容的提问来源于stack exchange,提问作者Erik Z
相关产品推荐
相关产品推荐

