私はMouseEvent
Reactからインポートします
import { MouseEvent } from 'react';
MouseEvent
以下の用途に使用
const closeSelectBox = (e: MouseEvent): void => {
if (!searchOptionWrapRef.current?.contains(e.target)) {
setOpenSelectBox(false)
}
};
私は自分のcloseSelectBox
useEffect(() => {
document.addEventListener("click", closeSelectBox);
return () => {
document.removeEventListener("click", closeSelectBox);
};
}, [])
searchOptionWrapRef
はdiv
const searchOptionWrapRef = useRef<HTMLDivElement>(null);
<div ref={searchOptionWrapRef}/>
しかし、次のエラーが発生します
Argument of type 'EventTarget' is not assignable to parameter of type 'Node'.
Type 'EventTarget' is missing the following properties from type 'Node': baseURI, childNodes, firstChild, isConnected, and 43 more.
any
の代わりにを使用せずにこの型エラーを解決するにはどうすればよいですかMouseEvent
?
ベストアンサー1
Reactによってエクスポートされるイベントインターフェースは、addEventListener
ハンドラーではなくReactイベントハンドラープロパティ用です。しないReact からインポートするMouseEvent
と、代わりに で動作する DOM グローバル インターフェイスが取得されますaddEventListener
。確かに、混乱しますね。:-)
しかし、2 番目の問題 (実際にはこれが主な問題かもしれません) は、DOM グローバルがではなくとしてMouseEvent
定義されることです。あなたの場合、それは常に になります(具体的には) が、それが DOM タイプの定義方法です。これに対処するには、少なくとも 2 つの選択肢があります。target
EventTarget
Node
Node
Element
純粋主義者
本当に純粋主義的に(私はそうします)、型アサーション関数を使用して でtarget
あると主張することもできますNode
。
// In a utility library:
function assertIsNode(e: EventTarget | null): asserts e is Node {
if (!e || !("nodeType" in e)) {
throw new Error(`Node expected`);
}
}
// And then in your component:
const closeSelectBox = ({target}: MouseEvent): void => {
assertIsNode(target);
if (!searchOptionWrapRef.current?.contains(target)) {
setOpenSelectBox(false);
}
};
簡潔かつ実用的
あなた知るはtarget
でありNode
ではないnull
ので、型アサーション ( target as Node
) を使用できます。
const closeSelectBox = ({target}: MouseEvent): void => {
if (!searchOptionWrapRef.current?.contains(target as Node)) {
setOpenSelectBox(false);
}
};
私は実行時にチェックされない型アサーション (これは型アサーション関数 like が行うことです) が好きではないのでassertIsNode
、おそらく最初のアプローチを採用するでしょう。ただし、確信がある限られた状況では、1 つを検討するかもしれません。