React和TypeScript中的HOC输入错误

时间:2018-12-29 10:22:26

标签: reactjs typescript

我正在尝试在React和TypeScript中实现HOC,但遇到类型错误。

这是HOC:

import * as React from "react";

interface IProps {
  loading: boolean;
}

const withLoader = <P extends object>(
  Component: React.ComponentType<P>
): React.ComponentType<P & IProps> => ({ loading, ...props }: IProps) =>
  loading ? (
    <div className="overlay">
      <div className="loader" />
    </div>
  ) : (
    <Component {...props} />
  );
export default withLoader;

反应类型的版本为:

"devDependencies": {
  "@types/react": "^16.7.18",
  "@types/react-dom": "^16.0.11",
  ...
}

react的版本是:

"dependencies": {
  "react": "^16.7.0",
  "react-dom": "^16.7.0",
  ...
}

我得到的错误是:

类型“ {}”不能分配给类型“ P”。ts(2322)

enter image description here

有人有什么主意吗?

1 个答案:

答案 0 :(得分:1)

似乎您的类型不匹配:您的HOC的返回类型为:React.ComponentType<P & IProps>,但实际上要返回的函数的类型为(props: IProps) => React.ReactNode。如果您成功(props: P & IProps) => React.ReactNode,它将停止抱怨。就是说,他们以这种方式输入此HOC将是:

function withLoader<P extends IProps>(Component: React.ComponentType<P>) {
  const Inner: React.FC<P> = props => { // the return type is inferred by the compiler
    if (props.loading) {
      return (
        <div className="overlay">
          <div className="loader" />
        </div>
      )
    }
    return <Component {...props} />
  }

  return Inner // return type is React.FC<P>
}

这将使加载道具保留在组件上,尽管一旦到达您的组件,它将始终为false

最后的想法:我发现自己已经离开了HOC,因为它们很难打字。如果您关心类型安全性,则可能更喜欢只使用渲染道具(可能不适用于此用例)或在组件中手动处理它。它可能更冗长,但更容易键入且更明确。我的观点:在TypeScript中,HOC并不是最简单的方法,因此我非常谨慎地使用它们。