【问题标题】:React HOC has a Typescript error as a class component but not as a function componentReact HOC 作为类组件而不是函数组件有 Typescript 错误
【发布时间】:2021-01-31 14:11:59
【问题描述】:

打字稿 - v3.9.7

我有一个向组件传递额外道具的 HOC:

import React from 'react';

interface IWithOwner {
    owner: string;
}

type IWithoutOwner<T extends IWithOwner> = Omit<T, keyof IWithOwner> & {owner?: never};

// CORRECT
export function withOwnerOne<TProps extends IWithOwner>(Component: React.ComponentType<TProps>) {
    const ComponentWithOwner: React.FunctionComponent<IWithoutOwner<TProps>> = (props) => {
        return (
            <Component
                owner="Tom"
                {...props}
            />
        );
    }

    return ComponentWithOwner;
}

// ERROR
export function withOwnerTwo<TProps extends IWithOwner>(Component: React.ComponentType<TProps>) {
    return class extends React.Component<IWithoutOwner<TProps>> {
        render() {
            return (
                // '{ owner: string; } & Readonly<IWithoutOwner<TProps>> & Readonly<{ children?: ReactNode; }>'
                // is assignable to the constraint of type 'TProps', but 'TProps' could be
                // instantiated with a different subtype of constraint 'IWithOwner'.
                <Component
                    owner="Tom"
                    {...this.props}
                />
            )
        }
    }
}

withOwnerOne 使用 Function 组件可以正常工作。而使用类组件的withOwnerTwo 有错误。为什么它们的工作方式不同?

Playground link

Same case with functions works correctly

【问题讨论】:

  • 对我来说这两种情况都失败了
  • @Drag13 也许这取决于打字稿版本或其他东西。你看过游乐场链接吗?
  • 它在操场上,在我更改了一些符号并撤消更改后

标签: reactjs typescript higher-order-components react-typescript


【解决方案1】:

我认为问题出在props 类型中。

在第一个示例中,FunctionComponentprops 的类型为:IWithoutOwner&lt;TProps&gt; &amp; { children?: ReactNode };

interface IWithOwner {
  owner: string;
}

type IWithoutOwner<T extends IWithOwner> = Omit<T, keyof IWithOwner> & {
  owner?: never;
};

function withOwnerTwo<TProps extends IWithOwner>(
  Component: React.ComponentType<TProps>
) {
  const ComponentWithOwner: React.FunctionComponent<IWithoutOwner<TProps>> = (
    props
  ) => {

    //  React.PropsWithChildren<IWithoutOwner<TProps>>   -->    IWithoutOwner<TProps> & { children?: ReactNode };
    const x = props; 
    return <Component owner="Dmitry" {...props} />;
  };

  return ComponentWithOwner;
}

其次,props 的类型有点不同:

Readonly&lt;IWithoutOwner&lt;TProps&gt;&gt; &amp; Readonly&lt;{children?: React.ReactNode;}&gt;

function withOwnerOne<TProps extends IWithOwner>(
  Component: React.ComponentType<TProps>
) {
  class Wrapper extends React.Component<IWithoutOwner<TProps>> {
    render() {
      //Readonly<IWithoutOwner<TProps>> & Readonly<{children?: React.ReactNode;}>
      const props = this.props; 

      return <Component owner="Dmitry" {...props} />;
    }
  }

  return Wrapper;
}

现在,您可能认为问题出在Readonly 修饰符上。 Readonly 不会导致错误。我坚信,这个错误是由逆变引起的。

因为props的类型取自组件上下文,而props generic被放置在上述组件的不同位置。

我愿意接受批评,所以请随时指出我的错误。

协方差/方差/不变性 - 对我来说太复杂的话题,我感觉比理解更多。所以,如果你指出我正确的方式,我会很高兴。

【讨论】:

    猜你喜欢
    • 2018-08-22
    • 2019-11-09
    • 2020-11-07
    • 2020-08-12
    • 2020-07-28
    • 2019-01-29
    • 2019-12-13
    • 2023-03-09
    • 1970-01-01
    相关资源
    最近更新 更多