180 lines
5.5 KiB
TypeScript
180 lines
5.5 KiB
TypeScript
/**
|
|
* 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;
|
|
}
|