从不同事件触发的Lambda的Typescript语法

8
使用Serverless框架,我定义了一个Lambda函数,可以按照每小时触发,或通过SNS触发。
  ...
  functions: {
    fooAction: {
      handler: 'handler.fooAction',
      events: [
        {
          schedule: 'rate(1 hour)',
        },
        {
          sns: {
            topicName: 'fooTopic',
          },
        },
      ],
    },
   ...
  }
  ...

当定义 fooAction 函数时,正确的 TypeScript 语法是什么?

我尝试过:

import { SNSHandler, ScheduledHandler} from 'aws-lambda';
...
export const fooAction: ScheduledHandler | SNSHandler = async (evt) => { ... };

但是evt解析为any
1个回答

17

在aws-lambda sdk中似乎有一个名为Handler的类型,它是通用的,可以用于类似这种情况的情形。

import { SNSEvent, EventBridgeEvent, Handler } from 'aws-lambda';

const fooHandler: Handler<SNSEvent | EventBridgeEvent<any, any>> = (event) => {
    if ('Records' in event ) {
        // SNSEvent
        const records = event.Records;
        // so something
    } else {
        const { id, version, region, source } = event;
    }
};

你还可以基于这两种不同的函数类型定义自己的类型。

type CustomEvent = (event: SNSEvent | EventBridgeEvent<"Scheduled Event", any>, context: Context, callback: Callback<void>) => Promise<void> | void

接着,使用这个新类型与你的lambda函数一起使用,

const fooHandler: CustomEvent = (event) => {
    if ('Records' in event ) {
        // SNSEvent
        const records = event.Records;
        // so something
    } else {
        const { id, version, region, source } = event;
    }
};

4
在研究相同用例时,偶然发现了这条评论。考虑为每个事件源创建一个 Lambda 函数,以避免在 Lambda 函数内部使用 if/else 逻辑。 - Seth Geoghegan
我认为 EventBridgeEvent<"Scheduled Event", any> 应该改为 EventBridgeEvent<"Scheduled Event", string>。因为EventBridge似乎会将细节转换为JSON字符串。 - gamliela

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接