import { EventEmitter } from "events"; export interface Builtins { newListener(event: string, listener: EventReceiver): void; } export type EventMap = Record; export type EventKey = string & keyof T; export type EventReceiver = (params: T) => void; export class TypedEmitter { readonly _emitter = new EventEmitter(); addListener>( eventName: K, fn: (T & Builtins)[K], ): void { this._emitter.addListener(eventName, fn); } on>( eventName: K, fn: (T & Builtins)[K], ): void { this._emitter.on(eventName, fn); } off>( eventName: K, fn: (T & Builtins)[K], ): void { this._emitter.off(eventName, fn); } removeListener>( eventName: K, fn: (T & Builtins)[K], ): void { this._emitter.removeListener(eventName, fn); } emit>( eventName: K, ...params: Parameters<(T & Builtins)[K]> ): void { this._emitter.emit(eventName, ...params); } once>( eventName: K, fn: (T & Builtins)[K], ): void { this._emitter.once(eventName, fn); } setMaxListeners(max: number): void { this._emitter.setMaxListeners(max); } listenerCount(eventName: string): number { return this._emitter.listenerCount(eventName); } listeners>( eventName: K, ): (T & Builtins)[K][] { return this._emitter.listeners(eventName) as any; } // We intentionally don't expose removeAllListeners because it would break Replicants when used. }