// type FireKey = string type FireFN = (...argu: any[]) => void class FireEvent> { #events: Record = {} as any print() { Object.keys(this.#events).forEach(key => { console.log(`${key}: ${this.#events[key]}\n`) }) } on(name: S, fn: T[S]) { if (!this.#events[name]) { this.#events[name] = [] } this.#events[name].push(fn) } emit(name: S, ...argu: Parameters) { if (this.#events[name]) { this.#events[name].forEach(fn => { fn(...argu) }) } } off(name: S, fn?: T[S]) { const len = this.#events[name].length if (!len) { return } if (!fn) { this.#events[name] = [] } else { for (let i = len - 1; i >= 0; i--) { const _fn = this.#events[name][i] if (_fn === fn) { this.#events[name].splice(i, 1) } } } } once(name: S, fn: T[S]) { const _fn: any = (...argu: any[]) => { fn(...argu) this.off(name, _fn) } this.on(name, _fn) } } export function buildEmitter>() { return new FireEvent() }