TypeScript联合类型问题:AWS Lambda事件类型联合未按预期工作
问题分析与解决
先给你说清楚:联合类型正常工作的核心是TypeScript能自动窄化类型,如果编译器没法从代码逻辑里判断当前值属于联合类型中的哪一个,就会要求你明确类型——这时候要么用类型守卫帮编译器识别,要么用类型断言。
你的问题出在AWS Lambda的EventBridgeEvent和SQSEvent这两个类型上:它们没有让TS编译器自动区分的独特标识,直接用typeof判断肯定没用——因为两者都是对象,typeof返回的都是object,编译器还是搞不清到底是哪一种。
解决方法:写自定义类型守卫
不用依赖类型断言,写两个简单的函数帮TS识别事件类型:
import { EventBridgeEvent, SQSEvent } from 'aws-lambda'; // 判断是否为EventBridge事件 function isEventBridgeEvent(event: any): event is EventBridgeEvent<any, any> { return 'detail-type' in event && 'detail' in event; } // 判断是否为SQS事件 function isSQSEvent(event: any): event is SQSEvent { return 'Records' in event && event.Records[0]?.eventSource === 'aws:sqs'; } // 调用processData前先做类型判断 function handleEvent(event: EventBridgeEvent<any, any> | SQSEvent) { if (isEventBridgeEvent(event)) { processData(event); // 这里TS自动知道event是EventBridgeEvent类型 } else if (isSQSEvent(event)) { processData(event); // 这里自动识别为SQSEvent类型 } } function processData(data: EventBridgeEvent<any, any> | SQSEvent) { // 你的处理逻辑 }
为什么之前的联合类型没生效?
当你直接把EventBridgeEvent<any,any> | SQSEvent作为参数传给processData时,如果调用前没做类型窄化,TS会默认要求传入的对象同时符合两个类型的结构(也就是两者的交集),这就导致你感觉它“只要求符合SQSEvent结构”——其实是要求同时满足两者,而你的数据肯定只符合其中一种,所以报错。
只有当你通过类型守卫(不管是自定义的还是TS内置的)让编译器明确当前值属于联合类型的某一个分支时,联合类型才会按预期工作,这时候就不需要类型断言了。
内容的提问来源于stack exchange,提问作者InquisitiveGirl
相关产品推荐
相关产品推荐

