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} />; }; }
逻辑说明
FullProps:代表InnerComponent需要的完整属性类型,由TypeScript自动从传入的组件推断得出。ProvidedProps:代表HOC要为组件提供的属性子集,必须是FullProps的一部分。Omit<FullProps, keyof ProvidedProps>:计算出父组件需要传入的属性类型(即排除HOC提供的属性)。- 合并
outerProps和providedProps后,得到的正是InnerComponent需要的FullProps,TypeScript会自动确认类型匹配,消除错误。
内容的提问来源于stack exchange,提问作者Vidar S. Ramdal
相关产品推荐
相关产品推荐

