reactjs Typescript错误,React高阶组件

vbkedwbf  于 2023-08-04  发布在  React
关注(0)|答案(1)|浏览(115)

长期的React开发人员试图适应typescript。
我在这个简单的高阶组件上获得正确的键入时遇到了问题

/**
 *  Returns a component that will have a default set of classnames
 */

function withDefaultClasses<T extends JSX.IntrinsicAttributes>(
  Component: React.FunctionComponent<T>,
  defaultClassNames: string,
) {
  
   type Props = T & { className?: string };

  return function withClasses(props: T & { className?: string }) {
    const { className, ...rest } = props;

    // Check if className is present or not before concatenating
    const classNames = className
      ? defaultClassNames + ' ' + className
      : defaultClassNames;

    return <Component className={classNames} {...rest} />;
  };
}

字符串
我收到以下错误

Type '{ className: string; } & Omit<Props, "className">' is not assignable to type 'IntrinsicAttributes & T'.
  Type '{ className: string; } & Omit<Props, "className">' is not assignable to type 'T'.
    'T' could be instantiated with an arbitrary type which could be unrelated to '{ className: string; } & Omit<Props, "className">'.


我相信这是由于通用组件可能没有className属性的事实。
我不知所措
我希望不会看到 typescript 错误

s4n0splo

s4n0splo1#

在这个高阶函数中,您尝试使用额外的props扩展React组件。您面临的问题是TypeScript不知道您提供的组件(Component)接受className属性。
您可以做的是创建一个新类型,扩展T并包含className。就像这样:

function withDefaultClasses<T extends React.ComponentProps<any>>(
  Component: React.ComponentType<T>,
  defaultClassNames: string,
) {
  return function withClasses(props: T) {
    const { className, ...rest } = props;

    // Check if className is present or not before concatenating
    const classNames = className
      ? defaultClassNames + ' ' + className
      : defaultClassNames;

    // We spread the rest props and add our concatenated className
    return <Component {...rest as T} className={classNames} />;
  };
}

字符串
在上面的代码中,React.ComponentProps<any>允许我们确保T始终包含className作为可能的属性。React.ComponentType<T>是一种更通用的组件类型,允许函数和类组件。rest props上的as TAssert允许TypeScript理解这些属性是针对Component的。
这应该可以解决TypeScript错误。它假定您使用withDefaultClasses Package 的原始组件(或多个组件)可以接受className属性。如果不是这种情况,您可能需要相应地调整类型或组件。

相关问题