Here's the code:
function bodyClickHandler(ev: MouseEvent) {
if(containerRef.current && containerRef.current.contains(ev.target)) return;
setOpen(false);
}
The error:
Argument of type 'EventTarget | null' is not assignable to parameter of type 'Node | null'. Type 'EventTarget' is missing the following properties from type 'Node': baseURI, childNodes, firstChild, isConnected, and 44 more.ts(2345)
containerRef.current
is a HTMLDivElement
. .contains
ought to be this function.
Is ev.target
not guaranteed to be a Node
of some sort?
I can cast it (ev.target as Node
) but I'm trying to figure out in what scenario this could possibly fail? What can I click on that isn't a Node?
Short answer: It's due to poor typings on their part. Go ahead and cast it.
Long answer: The reason this happens is because if you click on an <svg />
inside a button (for example), the event.target
will point to the SVG, which is not guaranteed to be a button (obviously). Only an event's currentTarget
points to the element the handler's on. Therefore the people who made the React typings decided that they would define and event's currentTarget
as what the button
was in our example, but make no guarantees about the event's target
except that it is an EventTarget. Therefore you are stuck with having to cast it. This is discussed in this PR.
I'm just starting with Typescript. I have a similar problem, my solution is, I know that the event is always fired by a DomElement.
And this is how I inform Typescript:
function bodyClickHandler(ev: MouseEvent) {
if(containerRef.current && containerRef.current.contains(ev.target as HTMLElement)) return;
setOpen(false);
}
If you prefer to separate it:
function bodyClickHandler(ev: MouseEvent) {
const target = ev.target as HTMLElement;
if(containerRef.current && containerRef.current.contains(target)) return;
setOpen(false);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With