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

TypeScript中如何定义泛型Lambda并为Handler指定特定参数类型?

在TypeScript中定义带指定参数类型和返回类型的Lambda函数

问题根源

你之前定义的Handler<Type>是一个泛型函数类型:

type Handler<Type> = {
  <Param extends unknown> (value:Param, ...args:unknown[]):Type;
}

这个类型要求函数能接收任意类型的value参数(因为Param是函数本身的泛型参数,调用时可指定任意类型),但你写的foo只能接受number,bar只能接受Date,所以TypeScript判定类型不兼容——泛型函数必须能处理所有可能的Param类型,而你的函数做不到。

解决方案:调整Handler的泛型结构

把参数类型从函数的泛型参数,移到Handler类型本身的泛型参数中,让每个Handler可以明确指定自己的参数类型,同时统一返回值类型:

1. 重新定义类型

// Handler 现在接收两个泛型参数:参数类型 Param,返回值类型 ReturnType
type Handler<Param, ReturnType> = (value: Param, ...args: unknown[]) => ReturnType;

// Handlers 定义为键是字符串,值为任意参数类型、固定返回值类型的 Handler
type Handlers<ReturnType> = Record<string, Handler<any, ReturnType>>;

2. 正确定义strHandlers

const strHandlers: Handlers<string> = {
  // 指定value为number,precision为number,返回string
  foo: (value: number, precision: number) => value.toFixed(precision),
  // 指定value为Date,返回string(注意原代码的toSIOString是笔误,应为toISOString)
  bar: (value: Date) => value.toISOString()
};

3. 更精确的类型约束(可选)

如果你想让strHandlers的每个属性都有明确的参数类型定义,可以直接写出具体的类型结构,避免使用any:

const strHandlers: {
  foo: Handler<number, string>;
  bar: Handler<Date, string>;
} = {
  foo: (value: number, precision: number) => value.toFixed(precision),
  bar: (value: Date) => value.toISOString()
};

针对补充问题的解释

你之前写的:

const foo: Handler<string> = (value:number, precision:number) => value.toFixed(precision);

定义时报错是因为Handler<string>要求函数能接受任意Param类型的value,但你的函数只能处理number。调用时不报错是因为TypeScript调用泛型函数时,会根据传入的参数自动推断Param为number,但这只是调用时的临时类型,和定义时的类型要求不匹配。

调整为新的Handler类型后,就可以正确定义:

const foo: Handler<number, string> = (value: number, precision: number) => value.toFixed(precision);
const str = foo(3.1415, 2); // 完全类型安全,无报错

内容的提问来源于stack exchange,提问作者Yanick Rochon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:20:59