无法在 Typescript 中编写高阶组件:JSX 元素类型没有任何构造或调用签名

Can't write higher order components in Typescript: JSX Element type does not have any construct or call signatures

是的,我知道有人问过这个问题,但我找到的 none 个答案解决了这个问题。我正在用 Typescript 编写一个简单的高阶组件,以在呈现组件之前验证授权。到目前为止它看起来像这样:

export function withAuth(Component: React.ComponentType) {

    if (!Component) return null;

    useEffect(() => {
        verifyToken().then(res => console.log(res))
    }, []);

    return (
        <Component/>
    )
}

我有一个名为 EditorContainer 的更大的 FunctionComponent,我将其传递给 HOC 并从其自己的文件中导出:export default withAuth(EditorContainer)

导入为 import EditorContainer from "./modules/Editor/containers/EditorContainer"; 并抛出此错误。

我试过了:

  1. 向 HOC 传递一个组件的新实例而不是它的实例 构造函数。这会引发不同的错误。
  2. 正在更改或删除所有类型。错误仍然存​​在。
  3. 正在更新 react, react-dom, @types/react@types/react-dom
  4. 将 withAuth 大写为 WithAuth(我 运行 没有想法)。
  5. 正在从其原始位置移除组件(由 React Router 路由渲染)。没有区别。

似乎不​​允许在 TypeScript 中编写高阶组件。

通过将 HOC 定义为 curried function 解决了这个问题。 :

export const withAuth = (Component: ComponentType<any>) => (props: any) => {

    const AuthWrapper: FunctionComponent = (props: any) => {
        const [auth, setAuth] = useState<any>(null);

        useEffect(() => {
            verifyToken().then(res => {
                console.log(res);
                setAuth(res);
            })
        }, []);

        if (!auth) return <Result
            status="403"
            title="403"
            subTitle="Sorry, you are not authorized to access this page."
            extra={<Link to="/"><Button type="primary">Back Home</Button></Link>}
        />;

        return (
            <Component {...props} authUser={auth}/>
        )
    }

    return <AuthWrapper {...props}/>;

};

完全不知道为什么会这样,所以我猜这个问题还没有真正回答。显式返回一个函数与返回一个 FunctionComponent 有什么不同……是一个函数?特别是在剥离类型之后,我不清楚有什么区别。

请参阅我关于您的解决方案为何有效的评论;但是你可以删除额外的功能。

export function withAuth(Component: React.ComponentType) {

    if (Component == null) { return () => null; }
    return () => {
        useEffect(() => {
            verifyToken().then(res => console.log(res))
        }, []);

        return (
            <Component/>
        )
    };
}