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

如何在TypeScript中根据Sender类型推断对应Handler参数类型?

问题:根据EventEmitter类型推断对应的Handler类型

场景说明

代码库中有两种不同的EventEmitter实现:

type HandlerA = (data: boolean) => void;

type HandlerB = (data: number) => void; // HandlerB 与 HandlerA 类型不同

type EventEmitterA = {
  on(eventName: string, handler: HandlerA): void;
  // 其他方法省略...
};

type EventEmitterB = {
  on(eventName: string, handler: HandlerB): void;
  // 其他方法省略...
};

同时存在一个兼容这两种实现的JS模块:

class EventDisposer {
  registerEvent(sender, eventName, handler) {
    sender.on(eventName, handler);
  }
  // 其他方法省略...
}

该模块在TS/JS混合的代码库中广泛使用,需要将其从JS迁移为TS,且不能修改现有调用方代码。

初步尝试及报错

尝试直接用联合类型定义参数:

type Sender = EventEmitterA | EventEmitterB;

type Handler = HandlerA | HandlerB;

class EventDisposer {
  registerEvent(sender: Sender, eventName: string, handler: Handler) {
    sender.on(eventName, handler); // 此处报错
  }
}

报错信息:Argument of type 'Handler' is not assignable to parameter of type 'HandlerA & HandlerB'

二次尝试及报错

尝试通过泛型提取对应Handler类型:

type ExtractHandler<S extends Sender> = S extends EventEmitterA ? HandlerA : HandlerB;

// 单独测试类型提取是有效的
type handlerA = ExtractHandler<EventEmitterA>; // 类型为HandlerA
type handlerB = ExtractHandler<EventEmitterB>; // 类型为HandlerB

class EventDisposer2 {
  registerEvent<S extends Sender, H = ExtractHandler<S>>(sender: S, eventName: string, handler: H) {
    sender.on(eventName, handler); // 此处仍报错
  }
}

报错信息:Argument of type 'H' is not assignable to parameter of type 'HandlerA & HandlerB'

疑问

是否可以根据传入的Sender类型自动缩小Handler的类型?比如在registerEvent方法内部使用类型守卫实现?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 12:57:11