TypeScript:基于事件处理器实现事件名与Payload类型映射及提取
解决方案
需求1:实现类型安全的publish函数
我们可以基于现有处理器构建事件名到Payload的类型映射,无需递归即可避免类型深度问题:
- 先定义处理器的联合类型(如果是数组,可用
typeof processors[number]替代):
type Processors = Event1Processor | Event2Processor;
- 通过条件类型和
infer关键字构建映射关系:
type EventPayloadMap = { [K in Processors as K extends EventProcessor<infer E, infer P> ? E : never]: K extends EventProcessor<infer E, infer P> ? P : never; };
- 实现publish函数,利用泛型约束强制参数类型匹配:
function publish<T extends keyof EventPayloadMap>(eventName: T, payload: EventPayloadMap[T]) { // 这里可添加实际发布逻辑,比如根据事件名获取对应处理器并执行process // 示例: // const processor = getProcessorByEventName(eventName); // processor.process(payload); }
调用示例:
// 合法调用,类型匹配 publish(EventNames.EVENT_NAME_1, { somePayload1: "demo" }); // 非法调用,TypeScript直接抛出类型错误 publish(EventNames.EVENT_NAME_1, { somePayload2: "error" });
需求2:提取支持的事件名联合类型
从处理器联合/数组类型中提取事件名,用infer关键字即可实现:
从处理器联合类型提取
type SupportedEventNames = Processors extends EventProcessor<infer E, unknown> ? E : never; // 结果等价于:EventNames.EVENT_NAME_1 | EventNames.EVENT_NAME_2
从处理器数组提取
如果处理器是常量数组:
const processors = [new Event1Processor(), new Event2Processor()] as const; type ProcessorArray = typeof processors; type SupportedEventNamesFromArray = ProcessorArray[number] extends EventProcessor<infer E, unknown> ? E : never;
内容的提问来源于stack exchange,提问作者Aviran Cohen
相关产品推荐
相关产品推荐

