Next.js13+TS严格模式下addEventListener重载匹配失败求助
解决Next.js 13严格TypeScript模式下focusin事件监听器类型不匹配问题
错误原因
核心问题是混淆了React合成事件的FocusEvent与DOM原生的FocusEvent:
- 从
react导入的FocusEvent是React封装的合成事件类型,带有nativeEvent、isDefaultPrevented等React专属属性; document.addEventListener接收的是DOM原生的FocusEvent类型,两者结构不兼容;- 自定义的
Element接口不仅无效,还覆盖了全局DOM类型定义,进一步加剧类型冲突。
解决方案
步骤1:移除React的FocusEvent导入
删除从react导入的FocusEvent,直接使用全局的DOM原生FocusEvent类型(TypeScript会自动识别)。
步骤2:调整事件处理函数的类型断言
e.target的默认类型是EventTarget,需要断言为Element才能访问tagName属性,确保类型安全。
步骤3:删除无效的自定义Element接口
全局DOM的Element类型已有正确的addEventListener/removeEventListener定义,自定义接口会干扰原有类型逻辑。
修改后的完整代码
import { useState, useEffect } from 'react'; const useActiveElement = () => { const [active, setActive] = useState<Element | null>(null); const handleFocusIn = (e: FocusEvent) => { const target = e.target as Element; if (!target) return; if (target.tagName === 'BUTTON') return; setActive(target); }; useEffect(() => { document.addEventListener('focusin', handleFocusIn); return () => { document.removeEventListener('focusin', handleFocusIn); }; }, []); return active; };
额外说明
- 把
useState的类型从EventTarget改为Element | null,更符合focus事件target的实际类型; - 若要进一步提升类型安全性,可添加类型守卫替代断言:
const target = e.target; if (!(target instanceof Element)) return;
内容的提问来源于stack exchange,提问作者KujoKun
相关产品推荐
相关产品推荐

