TypeScript中如何实现Foo.Bar形式的React子组件
TypeScript 实现 React 复合组件(
父组件.子组件)调用方式 你看到的类型交叉思路是完全正确的,实现失败基本都是漏了运行时属性挂载,或者类型合并写法有误,以下是可直接复用的标准实现:
实现步骤
- 先独立实现所有子组件,不要一开始就耦合到父组件上
// 子组件Bar type BarProps = React.PropsWithChildren<{ // 可在此处自定义Bar的专属props }> const Bar = ({ children }: BarProps) => { return <div className="foo-bar">{children}</div> }
- 定义父组件,同时声明包含静态属性的交叉类型
import React from 'react' // 父组件自身的props type FooProps = React.PropsWithChildren<{ // 可在此处自定义Foo的专属props }> // 定义复合组件类型:父组件本身类型 + 静态子组件类型 type FooCompoundComponent = React.FC<FooProps> & { Bar: typeof Bar }
- 实现父组件,手动挂载静态子组件属性后再导出
注意: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
相关产品推荐
相关产品推荐

