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

如何导出挂载在使用React.forwardRef的组件上的子组件?

解决React forwardRef组件挂载子组件的TypeScript类型错误

问题场景

构建UI系统时,需要将一个组件作为静态属性挂载到使用forwardRef的组件上。不使用forwardRef时该操作正常,但添加forwardRef后出现TypeScript类型错误,提示静态属性不存在于ForwardRefExoticComponent类型上。

错误信息

Property 'Secondary' does not exist on type 
'ForwardRefExoticComponent<ForwardedRefProps & RefAttributes<HTMLButtonElement>>'

示例代码

interface ButtonProps extends React.HTMLAttributes<HTMLButtonElement> {}

export const ForwardRefButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
  function Button(props, ref) {
    return(
      <button ref={ref}>Ref is forwarded</button>
    )
  }
)

ForwardRefButton.Secondary = function () { // 此处出现类型错误
  return (
    <button>Secondary Button</button>
  )
}

解决方案

方法一:显式扩展组件类型

通过定义包含静态属性的组件类型,将forwardRef返回的组件断言为该类型,让TypeScript识别静态成员:

import React from 'react';

interface ButtonProps extends React.HTMLAttributes<HTMLButtonElement> {}

// 定义包含Secondary静态属性的组件类型
type ForwardRefButtonComponent = React.ForwardRefExoticComponent<
  ButtonProps & React.RefAttributes<HTMLButtonElement>
> & {
  Secondary: React.FC;
};

// 断言组件类型
export const ForwardRefButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
  (props, ref) => {
    return <button ref={ref} {...props}>Ref is forwarded</button>;
  }
) as ForwardRefButtonComponent;

// 挂载静态组件
ForwardRefButton.Secondary = () => <button>Secondary Button</button>;

方法二:封装组件对象

先创建内部的forwardRef组件,再将其赋值给一个包含静态属性的对象,并扩展类型:

import React from 'react';

interface ButtonProps extends React.HTMLAttributes<HTMLButtonElement> {}

// 内部forwardRef组件
const BaseButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
  (props, ref) => {
    return <button ref={ref} {...props}>Ref is forwarded</button>;
  }
);

// 扩展类型并添加静态属性
export const ForwardRefButton = BaseButton as typeof BaseButton & {
  Secondary: React.FC;
};

ForwardRefButton.Secondary = () => <button>Secondary Button</button>;

原因说明

React.forwardRef返回的默认类型ForwardRefExoticComponent并未包含自定义静态属性的定义,因此TypeScript会阻止添加未声明的属性。通过扩展类型并断言,我们可以告诉TypeScript该组件包含额外的静态成员,从而解决类型错误。这种做法完全允许在forwardRef组件上挂载静态函数或组件,只是需要明确的类型声明支持。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 07:02:13