/** | |
* An events map is an interface that maps event names to their value, which | |
* represents the type of the `on` listener. | |
*/ | |
export interface EventsMap { | |
[event: string]: any; | |
} | |
/** | |
* The default events map, used if no EventsMap is given. Using this EventsMap | |
* is equivalent to accepting all event names, and any data. | |
*/ | |
export interface DefaultEventsMap { | |
[event: string]: (...args: any[]) => void; | |
} | |
/** | |
* Returns a union type containing all the keys of an event map. | |
*/ | |
export type EventNames<Map extends EventsMap> = keyof Map & (string | symbol); | |
/** The tuple type representing the parameters of an event listener */ | |
export type EventParams< | |
Map extends EventsMap, | |
Ev extends EventNames<Map> | |
> = Parameters<Map[Ev]>; | |
/** | |
* The event names that are either in ReservedEvents or in UserEvents | |
*/ | |
export type ReservedOrUserEventNames< | |
ReservedEventsMap extends EventsMap, | |
UserEvents extends EventsMap | |
> = EventNames<ReservedEventsMap> | EventNames<UserEvents>; | |
/** | |
* Type of a listener of a user event or a reserved event. If `Ev` is in | |
* `ReservedEvents`, the reserved event listener is returned. | |
*/ | |
export type ReservedOrUserListener< | |
ReservedEvents extends EventsMap, | |
UserEvents extends EventsMap, | |
Ev extends ReservedOrUserEventNames<ReservedEvents, UserEvents> | |
> = FallbackToUntypedListener< | |
Ev extends EventNames<ReservedEvents> | |
? ReservedEvents[Ev] | |
: Ev extends EventNames<UserEvents> | |
? UserEvents[Ev] | |
: never | |
>; | |
/** | |
* Returns an untyped listener type if `T` is `never`; otherwise, returns `T`. | |
* | |
* This is a hack to mitigate https://github.com/socketio/socket.io/issues/3833. | |
* Needed because of https://github.com/microsoft/TypeScript/issues/41778 | |
*/ | |
type FallbackToUntypedListener<T> = [T] extends [never] | |
? (...args: any[]) => void | Promise<void> | |
: T; | |
/** | |
* Strictly typed version of an `EventEmitter`. A `TypedEventEmitter` takes type | |
* parameters for mappings of event names to event data types, and strictly | |
* types method calls to the `EventEmitter` according to these event maps. | |
* | |
* @typeParam ListenEvents - `EventsMap` of user-defined events that can be | |
* listened to with `on` or `once` | |
* @typeParam EmitEvents - `EventsMap` of user-defined events that can be | |
* emitted with `emit` | |
* @typeParam ReservedEvents - `EventsMap` of reserved events, that can be | |
* emitted by socket.io with `emitReserved`, and can be listened to with | |
* `listen`. | |
*/ | |
export class Emitter< | |
ListenEvents extends EventsMap, | |
EmitEvents extends EventsMap, | |
ReservedEvents extends EventsMap = {} | |
> { | |
/** | |
* Adds the `listener` function as an event listener for `ev`. | |
* | |
* @param ev Name of the event | |
* @param listener Callback function | |
*/ | |
on<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>( | |
ev: Ev, | |
listener: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev> | |
): this; | |
/** | |
* Adds a one-time `listener` function as an event listener for `ev`. | |
* | |
* @param ev Name of the event | |
* @param listener Callback function | |
*/ | |
once<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>( | |
ev: Ev, | |
listener: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev> | |
): this; | |
/** | |
* Removes the `listener` function as an event listener for `ev`. | |
* | |
* @param ev Name of the event | |
* @param listener Callback function | |
*/ | |
off<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>( | |
ev?: Ev, | |
listener?: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev> | |
): this; | |
/** | |
* Emits an event. | |
* | |
* @param ev Name of the event | |
* @param args Values to send to listeners of this event | |
*/ | |
emit<Ev extends EventNames<EmitEvents>>( | |
ev: Ev, | |
...args: EventParams<EmitEvents, Ev> | |
): this; | |
/** | |
* Emits a reserved event. | |
* | |
* This method is `protected`, so that only a class extending | |
* `StrictEventEmitter` can emit its own reserved events. | |
* | |
* @param ev Reserved event name | |
* @param args Arguments to emit along with the event | |
*/ | |
protected emitReserved<Ev extends EventNames<ReservedEvents>>( | |
ev: Ev, | |
...args: EventParams<ReservedEvents, Ev> | |
): this; | |
/** | |
* Returns the listeners listening to an event. | |
* | |
* @param event Event name | |
* @returns Array of listeners subscribed to `event` | |
*/ | |
listeners<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>( | |
event: Ev | |
): ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>[]; | |
/** | |
* Returns true if there is a listener for this event. | |
* | |
* @param event Event name | |
* @returns boolean | |
*/ | |
hasListeners< | |
Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents> | |
>(event: Ev): boolean; | |
/** | |
* Removes the `listener` function as an event listener for `ev`. | |
* | |
* @param ev Name of the event | |
* @param listener Callback function | |
*/ | |
removeListener< | |
Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents> | |
>( | |
ev?: Ev, | |
listener?: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev> | |
): this; | |
/** | |
* Removes all `listener` function as an event listener for `ev`. | |
* | |
* @param ev Name of the event | |
*/ | |
removeAllListeners< | |
Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents> | |
>(ev?: Ev): this; | |
} | |