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

TypeScript中如何实现Foo.Bar形式的React子组件

TypeScript 实现 React 复合组件(父组件.子组件)调用方式

你看到的类型交叉思路是完全正确的,实现失败基本都是漏了运行时属性挂载,或者类型合并写法有误,以下是可直接复用的标准实现:


实现步骤

  1. 先独立实现所有子组件,不要一开始就耦合到父组件上
// 子组件Bar
type BarProps = React.PropsWithChildren<{
  // 可在此处自定义Bar的专属props
}>
const Bar = ({ children }: BarProps) => {
  return <div className="foo-bar">{children}</div>
}
  1. 定义父组件,同时声明包含静态属性的交叉类型
import React from 'react'

// 父组件自身的props
type FooProps = React.PropsWithChildren<{
  // 可在此处自定义Foo的专属props
}>

// 定义复合组件类型:父组件本身类型 + 静态子组件类型
type FooCompoundComponent = React.FC<FooProps> & {
  Bar: typeof Bar
}
  1. 实现父组件,手动挂载静态子组件属性后再导出

注意:TS类型仅在编译阶段生效,必须写实际的属性挂载代码,否则运行时会直接报错

const Foo: FooCompoundComponent = ({ children }) => {
  return <div className="foo">{children}</div>
}

// 关键步骤:运行时挂载子组件,少了这步就会触发Foo.Bar is not a function错误
Foo.Bar = Bar

export default Foo

常见踩坑

  • 只在类型定义里写了Bar: typeof Bar,没写Foo.Bar = Bar:TS类型编译后会被完全擦除,运行时Foo对象上根本不存在Bar属性
  • 父组件用了forwardRef、memo等高阶组件包装时,要把高阶组件返回的类型作为交叉类型的基础,不要直接套用React.FC:
// forwardRef场景下的类型定义示例
type FooCompoundComponent = React.ForwardRefExoticComponent<
  FooProps & React.RefAttributes<HTMLDivElement>
> & {
  Bar: typeof Bar
}

const Foo = React.forwardRef<HTMLDivElement, FooProps>(({children}, ref) => {
  return <div ref={ref}>{children}</div>
}) as FooCompoundComponent

// 同样需要手动挂载静态属性
Foo.Bar = Bar
  • 不要用any绕过类型检查,否则会丢失所有组件props的类型提示和校验能力

实现完成后就可以直接使用预期的嵌套写法,TS会自动补全Foo.Bar,同时对所有组件的入参做类型校验。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 03:48:28