假设在我的代码库中,我有两个不同的EventEmitter实现. 例如,如下所示:
type HandlerA = (data: boolean) => void;
type HandlerB = (data: number) => void; // HandlerB is somehow different from 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.
基本try :
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'
.
What I would like to do is infer the type of Handler based on the type of the Sender (Emitter) so I don't need to change anything on the caller side. 类似于:
type ExtractHandler<S extends Sender> = S extends EventEmitterA ? HandlerA : HandlerB;
type handlerA = ExtractHandler<EventEmitterA>;
type handlerB = ExtractHandler<EventEmitterB>;
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'.
个
是否可以根据发送者的类型缩小处理程序的类型?我想我可以用registerEvent
分钟内的 typewriter .
完整示例:https://tsplay.dev/wQ8o7W
谢谢!