Javascript (ES11) Event System implementation

So I decided to implement a basic event system in JavaScript.

My goal was to support the following functions:

on – allows the user to register a handler on the event system that fires until it’s removed.

once – same as above, but only fires the first time, then removes itself.

emit – creates an event and fires all relevant handlers.

delete – deletes the specified handler from from the system.

class HandlerSet extends Map {

    set(handler, once = false) {
        if (typeof handler !== 'function') return

        super.set(handler, !once ? handler : (...args) => {

    forEach(...args) {

class EventSystem extends Map {

    set(type) {
        return super.set(type, new HandlerSet())

    on(type, handler, once = false) {
        (this.get(type) ?? this.set(type).get(type)).set(handler, once)

    once(type, handler) {
        this.on(type, handler, true)

    emit(type, ...args) {
        this.get(type)?.forEach(handler => handler(...args))

    delete(type, handler) {
        let set = this.get(type)

        if (set?.delete(handler) && set?.size === 0) {

I’m curious to see what peoples thoughts are on this implementation.

As far as I’m aware, it should be quite robust from a type safety standpoint, as well as quite predictable from a lifecycle standpoint.

If anyone can find any bugs in this, or suggest improvements, I’d like to hear from you!