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

React TypeScript泛型:如何解决无法分配给IntrinsicAttributes类型错误?

高阶组件(HOC) TypeScript类型错误解决

需求描述

我正在创建一个高阶组件(HOC),用于为组件提供部分属性值,使父组件使用该组件时无需传入这些属性。

预期目标

希望将如下组件:

<MyInnerComponent someProp="some value" suppliedProp="supplied value" />

用HOC包裹后:

const WrappedComponent = wrap(MyInnerComponent, () => ({suppliedProp: "supplied value"}))

父组件可简化使用:

<WrappedComponent someProp="some value" />

最终渲染结果为:

<div>someProp: some value, suppliedProp: supplied value</div>

现有HOC实现

export function wrap<
  DataProps,
  InnerComponentType extends React.ComponentType<Props>,
  Props extends DataProps
>(
  InnerComponent: InnerComponentType,
  dataPropsProvider: (
    props: Omit<React.ComponentProps<InnerComponentType>, keyof DataProps>
  ) => DataProps
) {
  return (
    outerProps: Omit<React.ComponentProps<InnerComponentType>, keyof DataProps>
  ) => {
    const dataProps: DataProps = dataPropsProvider(outerProps);
    // 问题所在:
    return <InnerComponent {...outerProps} {...dataProps} />;
  };
}

遇到的问题

渲染InnerComponent时出现TypeScript错误:

Type 'Omit<ComponentProps, keyof DataProps> & DataProps' is not assignable to type 'IntrinsicAttributes & LibraryManagedAttributes<InnerComponentType, Props>'

已尝试方案

曾为DataProps添加如下约束,试图匹配组件属性类型:

export function wrap<
  DataProps extends JSX.IntrinsicAttributes & JSX.LibraryManagedAttributes<InnerComponent, Props>,
  InnerComponentType extends React.ComponentType<Props>,
  Props extends DataProps
>(
  // ... 函数体省略
)

但这会导致循环约束问题,且我并不理解为何需要继承JSX.IntrinsicAttributes和JSX.LibraryManagedAttributes。

解决方案

问题根源在于原泛型参数的约束逻辑混乱,TypeScript无法推断出outerProps与dataProps合并后能匹配InnerComponent的完整属性类型。我们可以调整泛型参数的定义,让类型关系更清晰:

import React from 'react';

export function wrap<
  FullProps extends object,
  ProvidedProps extends Partial<FullProps>
>(
  InnerComponent: React.ComponentType<FullProps>,
  dataPropsProvider: (props: Omit<FullProps, keyof ProvidedProps>) => ProvidedProps
) {
  return (outerProps: Omit<FullProps, keyof ProvidedProps>) => {
    const providedProps = dataPropsProvider(outerProps);
    // 此时合并后的属性正好是FullProps,TypeScript能正确识别
    return <InnerComponent {...outerProps} {...providedProps} />;
  };
}

逻辑说明

  1. FullProps:代表InnerComponent需要的完整属性类型,由TypeScript自动从传入的组件推断得出。
  2. ProvidedProps:代表HOC要为组件提供的属性子集,必须是FullProps的一部分。
  3. Omit<FullProps, keyof ProvidedProps>:计算出父组件需要传入的属性类型(即排除HOC提供的属性)。
  4. 合并outerProps和providedProps后,得到的正是InnerComponent需要的FullProps,TypeScript会自动确认类型匹配,消除错误。

内容的提问来源于stack exchange,提问作者Vidar S. Ramdal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 07:10:33