Skip to content

Instantly share code, notes, and snippets.

@sstur
Last active January 26, 2024 15:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sstur/5183a59dcc1649db5bae30e016790d24 to your computer and use it in GitHub Desktop.
Save sstur/5183a59dcc1649db5bae30e016790d24 to your computer and use it in GitHub Desktop.
type Listener<T extends Array<unknown>> = (...args: T) => void;
export class EventEmitter<
E extends Record<string, Array<unknown>> = Record<never, []>
> {
private listenerMap: { [K in keyof E]?: Set<Listener<E[K]>> } = {};
on<K extends keyof E>(key: K, listener: Listener<E[K]>) {
return this.addListener(key, listener);
}
addListener<K extends keyof E>(key: K, listener: Listener<E[K]>) {
const { listenerMap } = this;
const listeners = listenerMap[key] ?? (listenerMap[key] = new Set());
listeners.add(listener);
return () => {
listeners.delete(listener);
};
}
off<K extends keyof E>(key: K, listener: Listener<E[K]>) {
return this.removeListener(key, listener);
}
removeListener<K extends keyof E>(key: K, listener: Listener<E[K]>) {
const listeners = this.listenerMap[key];
if (listeners) {
listeners.delete(listener);
}
}
emit<K extends keyof E>(key: K, ...args: E[K]) {
const listeners: Set<Listener<E[K]>> | undefined = this.listenerMap[key];
if (listeners) {
for (const listener of listeners) {
listener(...args);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment