type DefaultEventMap = { [eventType: string]: TypedEvent; }; declare const kDefaultPrevented: unique symbol; declare const kPropagationStopped: unique symbol; declare const kImmediatePropagationStopped: unique symbol; interface TypedEvent extends Omit, 'type'> { type: EventType; } declare class TypedEvent extends MessageEvent implements TypedEvent { #private; [kDefaultPrevented]: boolean; [kPropagationStopped]?: Emitter; [kImmediatePropagationStopped]?: boolean; constructor(...args: [DataType] extends [void] ? [type: EventType] : [type: EventType, init: { data: DataType; }]); get defaultPrevented(): boolean; preventDefault(): void; stopImmediatePropagation(): void; } /** * Brands a TypedEvent or its subclass while preserving its (narrower) type. */ type Brand = Event & { type: EventType; }; type InferEventMap> = Target extends Emitter ? EventMap : never; type TypedListenerOptions = { once?: boolean; signal?: AbortSignal; }; declare namespace Emitter { /** * Returns an appropriate `Event` type for the given event type. * * @example * const emitter = new Emitter<{ greeting: TypedEvent }>() * type GreetingEvent = Emitter.InferEventType * // TypedEvent */ type EventType, EventType extends keyof EventMap & string, EventMap extends DefaultEventMap = InferEventMap> = Brand; type EventDataType, EventType extends keyof EventMap & string, EventMap extends DefaultEventMap = InferEventMap> = EventMap[EventType] extends TypedEvent ? DataType : never; /** * Returns the listener type for the given event type. * * @example * const emitter = new Emitter<{ getTotalPrice: TypedEvent }>() * type Listener = Emitter.ListenerType * // (event: TypedEvent) => number */ type ListenerType, Type extends keyof EventMap & string, EventMap extends DefaultEventMap = InferEventMap> = (event: Emitter.EventType) => Emitter.ListenerReturnType extends [void] ? void : Emitter.ListenerReturnType; /** * Returns the return type of the listener for the given event type. * * @example * const emitter = new Emitter<{ getTotalPrice: TypedEvent }>() * type ListenerReturnType = Emitter.InferListenerReturnType * // number */ type ListenerReturnType, EventType extends keyof EventMap & string, EventMap extends DefaultEventMap = InferEventMap> = EventMap[EventType] extends TypedEvent ? ReturnType : never; } declare class Emitter { #private; constructor(); /** * Adds a listener for the given event type. * * @returns {AbortController} An `AbortController` that can be used to remove the listener. */ on(type: EventType, listener: Emitter.ListenerType, options?: TypedListenerOptions): typeof this; /** * Adds a one-time listener for the given event type. * * @returns {AbortController} An `AbortController` that can be used to remove the listener. */ once(type: EventType, listener: Emitter.ListenerType, options?: Omit): typeof this; /** * Prepends a listener for the given event type. * * @returns {AbortController} An `AbortController` that can be used to remove the listener. */ earlyOn(type: EventType, listener: Emitter.ListenerType, options?: TypedListenerOptions): typeof this; /** * Prepends a one-time listener for the given event type. */ earlyOnce(type: EventType, listener: Emitter.ListenerType, options?: Omit): typeof this; /** * Emits the given typed event. * * @returns {boolean} Returns `true` if the event had any listeners, `false` otherwise. */ emit(event: Brand): boolean; /** * Emits the given typed event and returns a promise that resolves * when all the listeners for that event have settled. * * @returns {Promise>} A promise that resolves * with the return values of all listeners. */ emitAsPromise(event: Brand): Promise>>; /** * Emits the given event and returns a generator that yields * the result of each listener in the order of their registration. * This way, you stop exhausting the listeners once you get the expected value. */ emitAsGenerator(event: Brand): Generator>; /** * Removes a listener for the given event type. */ removeListener(type: EventType, listener: Emitter.ListenerType): void; /** * Removes all listeners for the given event type. * If no event type is provided, removes all existing listeners. */ removeAllListeners(type?: EventType): void; /** * Returns the list of listeners for the given event type. * If no even type is provided, returns all listeners. */ listeners(type?: EventType): Array>; /** * Returns the number of listeners for the given event type. * If no even type is provided, returns the total number of listeners. */ listenerCount(type?: EventType): number; } export { type DefaultEventMap, Emitter, TypedEvent, type TypedListenerOptions };