admin管理员组

文章数量:1323335

I have this event listener in React:

document.removeEventListener("mouseup", this.handleDocumentClick);

This is one of the definitions of this method as per Flow's source code:

removeEventListener(type: MouseEventTypes, listener: MouseEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture): void;

It seems the listener must be of type MouseEventListener:

type MouseEventHandler = (event: MouseEvent) => mixed
type MouseEventListener = {handleEvent: MouseEventHandler} | MouseEventHandler

So it seems that I can type it like this:

handleDocumentClick = (evt: MouseEvent) => {

}

So far, no Flow errors. Now, I want to check if the event's target is inside another DOM node that I have stored in a React Ref:

$menu: React.ElementRef<typeof Menu>;

handleDocumentClick = (evt: MouseEvent) => {
    if (this.$menu !== null) {
        const menu = ReactDOM.findDOMNode(this.$menu);

        if (menu) {
            console.log(menu.contains(evt.currentTarget));
        }
    }
}

And I get this error:

 54:                     console.log(menu.contains(evt.currentTarget));
                                                   ^^^^^^^^^^^^^^^^^ EventTarget. This type is inpatible with the expected param type of
447:   contains(other: ?Node): boolean;
                        ^^^^ Node. See lib: /private/tmp/flow/flowlib_3e761601/dom.js:447

The contains method should work for the target of an event (which is a DOM node). What could be wrong here – perhaps the definition of contains in Flow?

I have this event listener in React:

document.removeEventListener("mouseup", this.handleDocumentClick);

This is one of the definitions of this method as per Flow's source code:

removeEventListener(type: MouseEventTypes, listener: MouseEventListener, optionsOrUseCapture?: EventListenerOptionsOrUseCapture): void;

It seems the listener must be of type MouseEventListener:

type MouseEventHandler = (event: MouseEvent) => mixed
type MouseEventListener = {handleEvent: MouseEventHandler} | MouseEventHandler

So it seems that I can type it like this:

handleDocumentClick = (evt: MouseEvent) => {

}

So far, no Flow errors. Now, I want to check if the event's target is inside another DOM node that I have stored in a React Ref:

$menu: React.ElementRef<typeof Menu>;

handleDocumentClick = (evt: MouseEvent) => {
    if (this.$menu !== null) {
        const menu = ReactDOM.findDOMNode(this.$menu);

        if (menu) {
            console.log(menu.contains(evt.currentTarget));
        }
    }
}

And I get this error:

 54:                     console.log(menu.contains(evt.currentTarget));
                                                   ^^^^^^^^^^^^^^^^^ EventTarget. This type is inpatible with the expected param type of
447:   contains(other: ?Node): boolean;
                        ^^^^ Node. See lib: /private/tmp/flow/flowlib_3e761601/dom.js:447

The contains method should work for the target of an event (which is a DOM node). What could be wrong here – perhaps the definition of contains in Flow?

Share asked Jan 24, 2018 at 22:58 David GomesDavid Gomes 5,84516 gold badges64 silver badges104 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 8 +100

You have a couple options, the easiest of which is probably just:

handleDocumentClick = (evt: MouseEvent) => {
    if (this.$menu !== null) {
        const menu = ReactDOM.findDOMNode(this.$menu);

        if (menu && evt.currentTarget instanceof Node) {
            console.log(menu.contains(evt.currentTarget));
        }
    }
}

But you can always cast currentTarget (you can cast to Node, but you'll need to cast to any first):

handleDocumentClick = (evt: MouseEvent) => {
    if (this.$menu !== null) {
        const menu = findDOMNode(this.$menu)

        if (menu) {
            // console.log(menu.contains(((evt.currentTarget: any): Node)))
            console.log(menu.contains((evt.currentTarget: any)))
        }
    }
}

The first option will protect in case you end up with some weird edge case (and you could always add a utility function like isNode or something to use repeatedly).

The property currentTarget is inherited from Event, which can have references to types other than Node.

本文标签: javascriptReact Flowtype Nodecontains() Event TargetStack Overflow