Skip to content

Instantly share code, notes, and snippets.

@web-crab
Created February 22, 2026 02:21
Show Gist options
  • Select an option

  • Save web-crab/870347ff3e60c320192ddb4fb3047ca7 to your computer and use it in GitHub Desktop.

Select an option

Save web-crab/870347ff3e60c320192ddb4fb3047ca7 to your computer and use it in GitHub Desktop.
export type EventMap = Record<string, unknown>;
export type Arguments<Arg> = Arg extends void ? [] : [Arg];
export type Listener<Arg> = (...args: Arguments<Arg>) => void;
export class EventEmitter<
Map extends EventMap,
K extends keyof Map = keyof Map,
> {
private map: {
[E in K]?: Set<Listener<Map[E]>>;
} = {};
on<E extends K>(event: E, listener: Listener<Map[E]>): this {
if (!this.map[event]) {
this.map[event] = new Set();
}
this.map[event].add(listener);
return this;
}
off<E extends K>(event: E, listener: Listener<Map[E]>): this {
if (!this.map[event]) return this;
this.map[event].delete(listener);
if (this.map[event].size === 0) {
delete this.map[event];
}
return this;
}
protected emit<E extends K>(event: E, ...args: Arguments<Map[E]>): this {
if (this.map[event]) {
for (const listener of this.map[event]) {
listener(...args);
}
}
return this;
}
protected dispose(): this {
this.map = {};
return this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment