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

TypeScript中如何定义接收不同Props类型React.FC的组件Prop类型

错误根因

你遇到的类型报错本质是TypeScript函数参数的逆变特性导致的:React.FC<Props>的泛型参数Props属于函数入参类型,是逆变的。
你定义的image: React.FC<ProductImageProps | OrderImageProps>表示这个组件需要兼容两种Props的任意一种作为入参,但你传入的ProductImage只能接受ProductImageProps、OrderImage只能接受OrderImageProps,都不满足“兼容两种入参”的要求,所以赋值失败,和XOR类型没有关系。

原思路的可行修正(不推荐)

如果你一定要沿用原实现,可以修改CustomDataTableProps的image类型为组件的联合类型,再对props做类型断言绕开校验:

interface CustomDataTableProps {
  // 其他原有属性保留
  image: React.FC<ProductImageProps> | React.FC<OrderImageProps>
  list: boolean
}

// 组件内创建元素时加类型断言
image: React.createElement(props.image, (props.list ?
  { orders: cartItems } :
  { src: product.src }
) as Parameters<typeof props.image>[0])

该方案的缺陷非常明显:后续新增其他图像组件时,需要不断修改CustomDataTableProps的image联合类型,同时还要维护组件内的props条件判断逻辑,扩展性、可维护性都很差。

更优的Render Prop方案

针对你后续还要新增更多条件渲染组件的场景,Render Prop是性价比最高的方案,完全不需要修改表格组件本身的逻辑,类型天然安全:

1. 修改表格组件Props定义

把固定的image组件属性改为渲染函数,接受当前行数据和list状态作为入参,返回渲染节点:

interface CustomDataTableProps {
  // 其他原有属性全部保留
  renderImage: (item: ICartItem, isList: boolean) => React.ReactNode
  list: boolean
}

2. 表格内直接调用渲染函数

不需要再做条件判断、创建元素的逻辑,直接调用传入的render函数即可:

const sampleData = sampleProducts.map((product: ICartItem) => {
  return {
    image: props.renderImage(product, props.list),
    // 其他原有数据保留
  }
})

3. 调用表格组件时自定义渲染逻辑

需要用什么组件直接在调用侧定义即可,完全不需要改动表格组件代码:

// 渲染商品图场景
<CustomDataTable
  // 其他属性省略
  list={false}
  renderImage={(product) => <ProductImage src={product.src} />}
/>

// 渲染订单列表场景
const cartItems = useSelector((state: RootState) => state.cart.cartItems)
<CustomDataTable
  // 其他属性省略
  list={true}
  renderImage={() => <OrderImage orders={cartItems} />}
/>

后续新增任何图像组件,都只需要在调用侧写对应的渲染逻辑即可,表格组件不需要做任何调整,适配性极强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 12:36:05