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

TypeScript:如何让函数集合中函数的参数类型可被正确推断?

当然可以做到!问题的核心在于你原来的FunctionCollection索引签名强制所有函数共享同一个参数类型(比如any),这会让TypeScript把具体函数的参数类型“抹平”成这个统一类型,导致ArgType无法推断出具体的string。要解决这个问题,我们需要让FunctionCollection允许每个函数保留自己的参数类型,而不是用统一的类型约束。

方案1:使用泛型映射类型定义FunctionCollection

我们可以把FunctionCollection定义为一个泛型类型,让每个键对应的函数参数类型由泛型参数指定:

// 保留原来的ArgType定义
type ArgType<F> = F extends (a: infer A) => any ? A : any;

// 定义泛版FunctionCollection,每个函数的参数类型对应T中对应键的类型
type FunctionCollection<T> = {
  [K in keyof T]: (s: T[K]) => any;
};

// 使用时指定泛型参数,或者让TypeScript自动推断
const fnCol: FunctionCollection<{ someFn: string }> = {
  someFn: (s: string) => 500
};

// 现在可以正确推断出string类型
type InferredType = ArgType<typeof fnCol["someFn"]>; // 类型为string

方案2:用辅助函数自动推断类型

如果你不想手动指定泛型参数,可以创建一个辅助函数让TypeScript自动推断每个函数的参数类型:

type ArgType<F> = F extends (a: infer A) => any ? A : any;

// 辅助函数,用于推断集合中每个函数的具体类型
function createFunctionCollection<T extends Record<string, (s: any) => any>>(collection: T): T {
  return collection;
}

// 调用函数时,TypeScript会自动推断每个函数的参数类型
const fnCol = createFunctionCollection({
  someFn: (s: string) => 500,
  anotherFn: (n: number) => "hello"
});

// 验证推断结果:
type StringType = ArgType<typeof fnCol["someFn"]>; // string
type NumberType = ArgType<typeof fnCol["anotherFn"]>; // number

为什么原来的写法不行?

原来的FunctionCollection用了{ [key: string]: (s: ???) => any }这种索引签名,意味着所有属性的函数必须共享同一个参数类型。如果你填any,TypeScript会把someFn的参数类型从string拓宽到any;如果填其他固定类型,又无法兼容不同参数类型的函数。而上面的两种方案都避免了这种“统一类型约束”,让每个函数能保留自己的具体参数类型,从而让ArgType可以正确推断。

内容的提问来源于stack exchange,提问作者Gerrit Begher

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:23:55