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
相关产品推荐
相关产品推荐

