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

TypeScript中如何定义Foo、Foo.Bar形式的React组件

TypeScript 实现React组件点语法访问静态子组件

报错原因

直接给React.FC类型声明的组件挂载额外属性时,TS会检测到当前组件类型定义中不存在对应属性,因此抛出类型错误。本质是默认的函数组件类型没有预定义你要挂载的静态子组件属性类型。

修复方案

方案1:交叉类型扩展组件类型

通过交叉类型给组件补充静态属性的类型定义,是最通用的实现方式:

import React from 'react';

interface IFooProps {
  title: string
}

interface IBarProps {
  content: string
}

// 定义Foo组件的完整类型:本身是接收IFooProps的函数组件,额外携带Bar子组件属性
type FooComponent = React.FC<IFooProps> & {
  Bar: React.FC<IBarProps>
}

const Foo: FooComponent = ({title}) => {
  return <div>{title}</div>
}

const Bar: React.FC<IBarProps> = ({content}) => {
  // 修复原代码中div未闭合的语法错误
  return <div>{content}</div>
}

// 挂载静态子组件,此时无类型报错
Foo.Bar = Bar;

export default Foo

方案2:Object.assign 自动推导类型

通过Object.assign合并组件和静态属性,TS会自动推导合并后的完整类型,不需要手动编写交叉类型:

import React from 'react';

interface IFooProps {
  title: string
}

interface IBarProps {
  content: string
}

const Foo: React.FC<IFooProps> = ({title}) => {
  return <div>{title}</div>
}

const Bar: React.FC<IBarProps> = ({content}) => {
  return <div>{content}</div>
}

// 合并组件与静态属性,TS自动推导类型
const FinalFoo = Object.assign(Foo, { Bar })

export default FinalFoo

调用效果

两种方案实现后,都可以直接使用你预期的点语法调用组件,TS会正常提供类型校验和代码提示:

import Foo from './Foo'

const Content = () => {
  return (
    <>
      <Foo title="title"/>
      <Foo.Bar content="content"/>
    </>
  )
}

注意事项

  • 两种实现都不会丢失原有组件的props类型校验,传参错误时TS会正常抛出提示
  • 原示例代码中存在两处语法问题需要修正:Bar组件的末尾div标签未闭合、content属性使用了中文全角引号,实际编写时要替换为英文半角符号

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 08:51:28