Skip to content

Instantly share code, notes, and snippets.

@JTRNS
Created July 18, 2023 20:24
Show Gist options
  • Save JTRNS/46b3815587c0568e7d7df7c3fd699a80 to your computer and use it in GitHub Desktop.
Save JTRNS/46b3815587c0568e7d7df7c3fd699a80 to your computer and use it in GitHub Desktop.
EventEmitter
/**
* A generic class that allows for the creation of events and listeners.
*
* @template T - An object type that defines the events and their data types.
*/
export default class EventEmitter<T> {
private events: { [K in keyof T]: Array<(data: T[K]) => void> } = {} as unknown as { [K in keyof T]: Array<(data: T[K]) => void> };
/**
* Adds a listener to an event.
*
* @template K - The event key.
* @param {K} event - The event to listen to.
* @param {(data: T[K]) => void} listener - The listener function.
* @returns {void}
*/
on<K extends keyof T>(event: K, listener: (data: T[K]) => void): void {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(listener);
}
/**
* Triggers an event and calls all the listeners attached to it.
*
* @template K - The event key.
* @param {K} event - The event to trigger.
* @param {T[K]} data - The data to pass to the listeners.
* @returns {void}
*/
emit<K extends keyof T>(event: K, data: T[K]): void {
if (!this.events[event]) {
return;
}
this.events[event].forEach((listener) => {
listener(data);
});
}
/**
* Removes a listener from an event.
*
* @template K - The event key.
* @param {K} event - The event to remove the listener from.
* @param {(data: T[K]) => void} listener - The listener function to remove.
* @returns {void}
*/
off<K extends keyof T>(event: K, listener: (data: T[K]) => void): void {
if (!this.events[event]) {
return;
}
this.events[event] = this.events[event].filter((l) => l !== listener);
}
/**
* Adds a listener that will only be called once and then removed.
*
* @template K - The event key.
* @param {K} event - The event to listen to.
* @param {(data: T[K]) => void} listener - The listener function.
* @returns {void}
*/
once<K extends keyof T>(event: K, listener: (data: T[K]) => void): void {
const onceListener = (data: T[K]) => {
listener(data);
this.off(event, onceListener);
};
this.on(event, onceListener);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment