You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取仅含函数的类型中函数的参数类型?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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 11:35:19