TypeScript:ev.target 和 Node.contains:EventTarget 不可分配给 Node

mpe*_*pen 7 html typescript

这是代码:

function bodyClickHandler(ev: MouseEvent) {
    if(containerRef.current && containerRef.current.contains(ev.target)) return;
    setOpen(false);
}
Run Code Online (Sandbox Code Playgroud)

错误:

'EventTarget | 类型的参数 null' 不能分配给类型为 'Node | 的参数 空值'。“EventTarget”类型缺少“Node”类型中的以下属性:baseURI、childNodes、firstChild、isConnected 和 44 more.ts(2345)

containerRef.current是一个HTMLDivElement.contains应该是这个功能

ev.target不能保证是一个Node某种形式的?

我可以投射它 ( ev.target as Node) 但我想弄清楚在什么情况下这可能会失败?我可以点击什么不是节点?

小智 14

我刚刚开始使用 Typescript。我有一个类似的问题,我的解决方案是,我知道该事件总是由 DomElement 触发。

这就是我通知 Typescript 的方式:

function bodyClickHandler(ev: MouseEvent) {
    if(containerRef.current && containerRef.current.contains(ev.target as HTMLElement)) return;
    setOpen(false);
}
Run Code Online (Sandbox Code Playgroud)

如果您喜欢将其分开:

function bodyClickHandler(ev: MouseEvent) {
    const target = ev.target as HTMLElement;
    if(containerRef.current && containerRef.current.contains(target)) return;
    setOpen(false);
}
Run Code Online (Sandbox Code Playgroud)


Rob*_*ore 12

简短回答:这是由于他们的打字不佳。继续投吧。

长答案:发生这种情况的原因是因为如果您单击<svg />按钮内部(例如),event.target将指向 SVG,这不能保证是按钮(显然)。只有事件currentTarget指向处理程序所在的元素。因此,制作 React 类型的人决定他们将定义和事件的currentTarget内容与button我们示例中的内容相同,但不对事件做出任何保证target除了它是一个 EventTarget。因此,您不得不强制转换它。本 PR对此进行了讨论。