React+TS forwardRef含children时Ref类型不匹配报错求助
React + TypeScript forwardRef 转发ref时类型不兼容报错修复
报错核心原因
出现该类型错误的根本原因是React.forwardRef的泛型参数顺序传错:
forwardRef的第一个泛型位,接收的是ref最终绑定的实例类型- 第二个泛型位,才是组件自身接收的Props类型
如果误将自定义Props类型填入第一个泛型位,TS会判定组件期望接收的ref指向Props类型实例,和你实际创建的、指向HTMLDivElement的ref类型冲突,就会抛出类型不匹配错误。
报错核心指向:
Type 'MutableRefObject<HTMLDivElement>' is not assignable to type 'Ref<Props>',即存储div实例的ref对象无法赋值给期望接收Props类型的ref。
错误写法对照
import { forwardRef, useRef } from 'react'; type MyCompProps = { children: React.ReactNode; } // ❌ 错误:泛型顺序写反,将Props类型填到了ref对应的泛型位 const MyComp = forwardRef<MyCompProps, MyCompProps>(({ children }, ref) => { // 此处给原生div传ref时会直接报类型错误 return <div ref={ref}>{children}</div> }) export default function Demo() { const divRef = useRef<HTMLDivElement>(null); // 此处传入ref时同样会触发类型校验失败 return <MyComp ref={divRef}>测试内容</MyComp> }
正确修复方案
严格按照forwardRef的泛型定义顺序传参:如果ref最终要绑定到原生div元素,第一个泛型参数传HTMLDivElement,第二个参数传组件自定义Props类型即可。
import { forwardRef, useRef } from 'react'; type MyCompProps = { children: React.ReactNode; className?: string; } // ✅ 正确:泛型顺序为<ref绑定的实例类型, 组件Props类型> const MyComp = forwardRef<HTMLDivElement, MyCompProps>(({ children, className }, ref) => { return <div ref={ref} className={className}>{children}</div> }) export default function Demo() { const divRef = useRef<HTMLDivElement>(null); // 此处传ref无类型报错,可正常获取div实例 return <MyComp ref={divRef} className="container">测试内容</MyComp> }
额外注意事项
- 组件包含
children不会触发该类报错,只要在Props类型中声明children: React.ReactNode,或使用内置类型React.PropsWithChildren<你的自定义Props>即可正确推导children类型 - 如果不是直接转发原生DOM ref,而是通过
useImperativeHandle向外暴露自定义方法/属性,第一个泛型参数要传你暴露出去的实例类型,不要传Props类型 - 不要通过给ref声明
any类型绕过校验,会丢失后续的实例属性、方法类型提示
内容的提问来源于stack exchange,提问作者meotimdihia
相关产品推荐
相关产品推荐

