Flow: EventTarget's addEventListener and removeEventListener definitions are too strict

Created on 18 Aug 2017  路  4Comments  路  Source: facebook/flow

I can't find a proper way to call addEventListener and type specifically e.target to be able to manipulate it.

I did 2 ways in my example code:

const element: HTMLElement = document.createElement('div');

function listener1(e: MouseEvent & { target: HTMLElement }) {
    e.target.remove();
}

function listener2(e: MouseEvent) {
    e.target.remove();
}

element.addEventListener('mousedown', listener1);
element.addEventListener('mousedown', listener2);

See also in Try.

I believe the definition of the event handlers in https://github.com/facebook/flow/blob/master/lib/dom.js#L125 are too strict but I don't have very good ideas atm. Any workaround suggestion is welcome :)

Accepting PRs Library definitions

Most helpful comment

Had the same issue. This worked for me, thanks @julienw

function listener2(e: MouseEvent) {
       const target: HTMLElement = (e.target: any);
    target.remove();
}

All 4 comments

Errors are:

    8:  e.target.remove();
                 ^ property `remove`. Property not found in
    8:  e.target.remove();
        ^ EventTarget
    11: element.addEventListener('mousedown', listener1);
        ^ call of method `addEventListener`. Function cannot be called on any member of intersection type
    11: element.addEventListener('mousedown', listener1);
        ^ intersection

My current workaround is replacing listener2 with:

function listener2(e: MouseEvent) {
       const target: HTMLElement = (e.target: any);
    target.remove();
}

Everytime someone uses any a puppy dies.

Maybe something similar to https://github.com/facebook/flow/commit/e44a2acc4629d8aa80e365bf9c4da7ea28e04ea5 could be done for non-synthetic events ?

Just to be clear, I think the title on this should be changed. It's not addEventListener's type that's wrong. It's the various Event types, where target is an EventTarget rather than a full HTMLElement. The difficulty here is that while the vast majority of use cases will have a DOM node as the event's target, it is perfectly possible to create your own EventTargets and send events with the same name as DOM events to them. I'm not sure that it's possible to distinguish on the type level whether a callback listener can expect to get a target that's a DOM node or not.

In the meantime, casting event.target to an element seems like the right workaround.

Had the same issue. This worked for me, thanks @julienw

function listener2(e: MouseEvent) {
       const target: HTMLElement = (e.target: any);
    target.remove();
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

cubika picture cubika  路  3Comments

ctrlplusb picture ctrlplusb  路  3Comments

john-gold picture john-gold  路  3Comments

funtaps picture funtaps  路  3Comments

ghost picture ghost  路  3Comments