TypeScript严格模式下useRef添加守卫子句仍报对象可能为null如何解决
问题原因
这不是TypeScript的bug,属于合法的类型校验提示,核心原因有两个:
- 你声明ref时没有指定泛型类型,当初始值传入
null时,TypeScript会默认将useRef的返回值推断为React.MutableRefObject<null>类型,其current属性会被永久判定为null类型,普通的非空判断无法触发类型收窄。 ref.current属于可变属性,TypeScript无法保证你在非空判断和调用focus方法的间隙,current的值没有被其他代码修改,因此即便是写了判断逻辑,也不会生效。
你最后写的空值合并运算符写法报错是因为:当??左侧的calendarSelectedDayRef为null时才会执行右侧代码,此时左侧已经为null,右侧再访问其current属性自然会得到never类型的报错。
修复方案
- 方案1:声明ref时指定正确的泛型类型(最推荐)
如果你要绑定的是DOM元素,比如对应日历日期的div元素,就按实际类型传入泛型:
之后再用临时变量收窄类型即可通过校验:// 按你实际绑定的DOM元素类型替换HTMLDivElement const calendarSelectedDayRef = useRef<HTMLDivElement>(null);const selectedEl = calendarSelectedDayRef.current; if (selectedEl) { selectedEl.focus(); } - 方案2:使用非空断言(仅推荐你100%确定current不为空时使用)
手动告诉TypeScript此处current一定不为空,跳过校验:calendarSelectedDayRef.current!.focus();
另外需要注意你提供的代码中存在变量名不一致的问题:你声明的ref是calendarRef,但实际使用的是calendarSelectedDayRef,请确认是否存在变量声明错误。
内容的提问来源于stack exchange,提问作者Alex Foxleigh
相关产品推荐
相关产品推荐

