我正在尝试在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)
有人有什么主意吗?
答案 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并不是最简单的方法,因此我非常谨慎地使用它们。