You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在TypeScript中如何正确使用forwardRef?自定义组件props报错怎么解决?

解决方案

你遇到的报错核心原因是TypeScript无法自动推导forwardRef包裹组件的自定义Props类型,需要你主动声明类型定义,具体修改方案如下:


方案1:支持动态tag的完整写法

如果你的组件需要支持通过tag属性动态切换渲染标签,可以用泛型实现完整的类型适配:

步骤1:定义Props类型

import type { ComponentProps, ElementType, ReactNode } from 'react'

interface AvatarProps<T extends ElementType = 'div'> {
  // 自定义属性,可根据业务调整可选值范围
  color?: string
  size?: 'sm' | 'md' | 'lg'
  className?: string
  tag?: T
  children?: ReactNode
  // 继承tag对应元素的所有原生属性
} & ComponentProps<T>

步骤2:给forwardRef添加泛型声明

import { forwardRef } from 'react'
import classnames from 'classnames'

const Avatar = forwardRef(<T extends ElementType = 'div'>(
  props: AvatarProps<T>, 
  ref: React.Ref<Element>
) => {
  const {
    color,
    className,
    size,
    tag: Tag = 'div', // tag默认值设为div
    ...rest
  } = props

  return (
    <Tag
      className={classnames('avatar', {
        [className]: className,
        [`bg-${color}`]: color,
        [`avatar-${size}`]: size
      })}
      ref={ref}
      {...rest}
    >
      {/* 其余业务代码 */}
    </Tag>
  )
}) as <T extends ElementType = 'div'>(props: AvatarProps<T> & React.RefAttributes<Element>) => React.ReactElement

export default Avatar

方案2:固定tag的简化写法

如果你的组件不需要动态切换渲染标签,默认固定为div,可以用更简洁的写法:

import { forwardRef, HTMLAttributes } from 'react'
import classnames from 'classnames'

// 直接声明Props,继承div原生属性
interface AvatarProps extends HTMLAttributes<HTMLDivElement> {
  color?: string
  size?: 'sm' | 'md' | 'lg'
  className?: string
}

// forwardRef两个泛型分别对应:ref指向的元素类型、组件Props类型
const Avatar = forwardRef<HTMLDivElement, AvatarProps>((props, ref) => {
  const { color, className, size, ...rest } = props
  return (
    <div
      className={classnames('avatar', {
        [className]: className,
        [`bg-${color}`]: color,
        [`avatar-${size}`]: size
      })}
      ref={ref}
      {...rest}
    >
      {/* 其余业务代码 */}
    </div>
  )
})

export default Avatar

调用验证

修改完成后两种调用方式都不会再报类型错误:

// 普通调用
<Avatar size="sm" color="success" />

// 传ref调用
const ref = React.createRef<HTMLDivElement>();
<Avatar ref={ref} size="sm" color="success" />

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 14:36:03