Skip to content

Instantly share code, notes, and snippets.

@bramblex
Created October 24, 2019 07:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bramblex/6741b50e97259de73d10f4458f6cd414 to your computer and use it in GitHub Desktop.
Save bramblex/6741b50e97259de73d10f4458f6cd414 to your computer and use it in GitHub Desktop.
type BaseEventMap = { [event: string]: [] }
type EventListener<EventMap extends BaseEventMap, Event extends keyof EventMap>
= (...args: EventMap[Event]) => any
type EventListenerItem<EventMap extends BaseEventMap, Event extends keyof EventMap> = {
once: boolean
listener: EventListener<EventMap, Event>
}
type Events<EventMap extends BaseEventMap> = {
[Event in keyof EventMap]?: EventListenerItem<EventMap, Event>[]
}
export class EventEmitter<EventMap extends BaseEventMap> {
private _events: Events<EventMap> = {}
emit<Event extends keyof EventMap>(event: Event, ...args: EventMap[Event]): boolean {
const listeners = this._events[event]
if (listeners && listeners.length > 0) {
listeners.forEach(({ listener }) => listener(...args))
this._events[event] = listeners.filter(({ once }) => !once)
return true
} else {
return false
}
}
on<Event extends keyof EventMap>(event: Event, listener: (...args: EventMap[Event]) => any): this {
const listeners = this._events[event]
const item = { listener, once: false }
if (listeners) {
listeners.push(item)
} else {
this._events[event] = [item]
}
return this
}
once<Event extends keyof EventMap>(event: Event, listener: (...args: EventMap[Event]) => any): this {
const listeners = this._events[event]
const item = { listener, once: true }
if (listeners) {
listeners.push(item)
} else {
this._events[event] = [item]
}
return this
}
off<Event extends keyof EventMap>(event?: Event, listener?: (...args: EventMap[Event]) => any): this {
if (!event) {
this._events = {}
} else if (!listener) {
delete this._events[event]
} else {
const listeners = this._events[event]
if (listeners) {
this._events[event] = listeners.filter(item => item.listener !== listener)
}
}
return this
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment