React TypeScript中useRef钩子异常:错误Ref类型未触发TS报错
HTMLInputElement类型的useRef赋值给div的ref时TypeScript未报错? 原因分析
React元素的ref属性接受LegacyRef<T>类型(T对应元素的DOM类型,比如div对应HTMLDivElement),而useRef<U>返回的是MutableRefObject<U | null>。在默认TypeScript配置(未开启严格模式)下,由于HTMLInputElement和HTMLDivElement均继承自HTMLElement,TypeScript的结构类型系统会宽松允许这类跨类型赋值,导致类型检查被绕过。此外,直接传递MutableRefObject给元素ref时,React的类型定义在部分场景下不会严格校验current属性的具体类型,仅校验结构是否符合RefObject规范。
触发预期类型错误的两种方法
开启严格类型检查
在tsconfig.json中启用strict模式(或至少开启strictNullChecks和strictFunctionTypes):{ "compilerOptions": { "strict": true } }开启后TypeScript会严格校验
RefObject泛型类型与元素DOM类型的匹配性,你的代码会直接抛出类型不匹配错误。使用回调Ref替代直接传递RefObject
将ref改为回调形式,此时TypeScript会明确检查赋值给ref.current的元素类型:import { useRef } from "react" export default function Box(){ const ref = useRef<HTMLInputElement>(null) return <div ref={(el) => { ref.current = el; }}>this is a div</div> }这段代码会立即触发错误:
Type 'HTMLDivElement | null' is not assignable to type 'HTMLInputElement | null',符合预期的类型校验结果。
额外提示
若项目依赖的@types/react版本较旧,可能存在类型定义不够严格的问题,建议升级到最新稳定版本以获得更准确的类型校验。
内容的提问来源于stack exchange,提问作者Aadi-23

