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

如何正确定义支持Callback与Promise的AWS Lambda Handler联合类型?

修复AWS Lambda Handler联合函数类型的类型校验问题

要正确建模支持回调和Promise两种返回方式的Handler类型,直接使用函数类型联合会导致TypeScript无法正确推断参数和返回值类型,推荐使用函数重载来定义类型,或者调整为交叉类型的函数签名(效果等同于重载)。

问题根源

当你使用函数类型联合时:

export type Handler<TEvent, TResult> = ((
    event: TEvent,
    context: Context,
    callback: Callback<TResult>,
) => void) | ((
    event: TEvent,
    context: Context,
) => Promise<TResult>);

TypeScript在赋值未显式标注参数类型的函数时,无法确定你要匹配联合中的哪个分支,因此会将参数推断为any,同时无法正确校验返回值类型。而回调分支能正常工作,是因为它的参数数量与联合中第一个函数类型完全匹配,TypeScript能直接匹配该分支。

解决方案:使用函数重载

通过接口或类型别名定义重载的函数签名,明确给出两种合法的实现方式:

方式1:接口形式的重载

type Context = { /* 实际的Context类型定义 */ };
type Callback<TResult> = (error: Error | null, result: TResult) => void;

export interface Handler<TEvent, TResult> {
  // 回调分支签名
  (event: TEvent, context: Context, callback: Callback<TResult>): void;
  // Promise分支签名
  (event: TEvent, context: Context): Promise<TResult>;
}

方式2:交叉类型的函数签名

如果你更倾向于使用类型别名而非接口,可以用交叉类型实现等效的重载效果:

export type Handler<TEvent, TResult> = 
  ((event: TEvent, context: Context, callback: Callback<TResult>) => void) &
  ((event: TEvent, context: Context) => Promise<TResult>);

验证修复效果

Promise分支(自动推断参数类型)

const handler: Handler<string, string> = (event, context) => {
  // event被推断为string,context为Context类型
  return Promise.resolve('wow'); // 返回值被校验为Promise<string>,符合要求
};

回调分支(正常校验)

const handler2: Handler<string, string> = (event, context, callback) => {
  // 所有参数类型均正确推断
  callback(null, 'Hello World'); // callback参数类型被正确校验
};

为什么重载能解决问题

重载签名明确告知TypeScript该函数允许两种不同的调用/实现方式,当你编写函数实现时,TypeScript会根据你提供的参数数量自动匹配对应的重载分支,从而正确推断参数类型并校验返回值。

内容的提问来源于stack exchange,提问作者Nate Glenn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 22:10:30