我正在尝试构建一个确保类型安全使用的通用事件处理程序系统。 应该不可能订阅错误的事件类型(例如不允许this.on('FooEvent', (event : BarEvent) => ...)
)。
这是到目前为止我得到的:
interface Event {
type: string;
}
type EventType<T extends Event> = T['type'];
type EventHandler<T extends Event> = (event: T) => void;
class TypedEventHandler<TEvent extends Event> {
private eventHandlers = new Map<
EventType<TEvent>,
EventHandler<TEvent>[]
>();
on<TOnEvent extends TEvent, TOnType extends TOnEvent['type']>(
type: TOnType,
handler: EventHandler<TOnEvent>,
) {
if (!this.eventHandlers.has(type)) {
this.eventHandlers.set(type, []);
}
this.eventHandlers.get(type)!.push(handler);
}
emit(event: TEvent) {
const handlers = this.eventHandlers.get(event.type);
if (!handlers) return;
handlers.forEach(handler => handler(event));
}
}
不幸的是,.push(handler)
失败,出现Argument of type 'EventHandler<TOnEvent>' is not assignable to parameter of type 'EventHandler<TEvent>'
。是否可以使eventHandlers
变量的类型更具体,以便可以分配处理程序?
我找到了similar questions like this,但是没有一个能真正回答我的问题。