You need to enable JavaScript to run this app. React自定义Hook中useRef值的正确TypeScript类型标注方法
优惠活动
大模型
产品
解决方案
定价
更多

React自定义Hook中useRef值的正确TypeScript类型标注方法

解决方案

问题1:接口myRef类型定义错误

你之前在接口中把myRef定义为HTMLElement | null,但useRef返回的不是DOM元素本身,是一个持有current属性的ref对象,类型为React.MutableRefObject<T>。
调整接口定义即可解决返回值报错问题,且HTMLElement是所有HTML元素的基类,不需要指定具体元素类型就能适配所有HTML元素的绑定需求。

问题2:el访问属性时报错

myRef.current的类型已经是你声明的HTMLElement | null,不需要额外标注类型。报错的原因是使用可选链后,el?.offsetWidth和el?.scrollWidth可能为undefined,直接比较会触发类型警告,只需要先判断el非空再执行比较逻辑,TS会自动将el推导为HTMLElement类型,不会再提示属性可能为undefined。


修正后的完整代码

import { useState, useRef, useEffect, MutableRefObject } from 'react';

interface MyHookInterface {
    someBooleanState: boolean
    myRef: MutableRefObject<HTMLElement | null>
}

const useMyHook = (): MyHookInterface => {
    const [someBooleanState, setSomeBooleanState] = useState<boolean>(false)
    const myRef = useRef<HTMLElement | null>(null)
  
    useEffect(() => {
      const el = myRef.current
      // 先判断el非空再执行逻辑
      if(el && el.offsetWidth < el.scrollWidth){
          // 执行业务逻辑
      }
    }, [])
  
    return {
        someBooleanState,
        myRef
    }
}

可选优化:泛型版本支持指定具体元素类型

如果后续需要针对特定元素做类型限制,可以改成泛型Hook,使用时可灵活指定绑定的元素类型:

import { useState, useRef, useEffect, MutableRefObject } from 'react';

interface MyHookInterface<T extends HTMLElement> {
    someBooleanState: boolean
    myRef: MutableRefObject<T | null>
}

const useMyHook = <T extends HTMLElement = HTMLElement>(): MyHookInterface<T> => {
    const [someBooleanState, setSomeBooleanState] = useState(false)
    const myRef = useRef<T | null>(null)
  
    useEffect(() => {
      const el = myRef.current
      if(el && el.offsetWidth < el.scrollWidth){
          // 执行业务逻辑
      }
    }, [])
  
    return {
        someBooleanState,
        myRef
    }
}

// 使用示例:指定绑定div元素
// const { myRef } = useMyHook<HTMLDivElement>()

内容的提问来源于stack exchange,提问作者theJuls

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 15:06:03