TypeScript 3: JSX element type 'Component' does not have any construct or call signatures. [2604]

旧城冷巷雨未停 提交于 2019-12-23 10:18:03

问题


I'm trying to pass a variable of type React.Component (or React.FunctionComponent) into a Route, like this:

import React from 'react';
import { Route } from 'react-router-dom';

type PrivateRouteProps = {
  component: React.Component | React.FunctionComponent;
  isAuthenticated: boolean;
  login: (...args: any[]) => any;
  path: string;
};

const PrivateRoute: React.FunctionComponent<PrivateRouteProps> = ({
  component: Component,
  isAuthenticated,
  login,
  path,
  ...rest
}) => {
  return (
    <Route
      path={path}
      {...rest}
      render={props => {
        if (isAuthenticated) {
          return <Component {...props} />;
        } else {
          login();
          return null;
        }
      }}
    />
  );
};

But I'm getting this error:

JSX element type 'Component' does not have any construct or call signatures. [2604]

I've read through a bunch of other threads about this issue, but they all seem to deal with this error coming up for a specific component implementation. I can't change the component in question or import it differently (like the accepted answers often suggest), because it could be any component.

I'm using TypeScript 3.1.6, Babel Core 7.1, and React 16.6.3.


回答1:


I have encountered this a couple of times. Try these:

  1. Type your PrivateRoute as React.SFC<Props>
  2. Type your incoming component as React.ReactType

The ultimate truth about React types comes from the docs




回答2:


Late to the party, with "@types/react-router-dom": "^4.3.4" and "@types/react": "16.9.1", and if you're using RouteProps, you will probably get the same error.

JSX element type 'Component' does not have any construct or call signatures. [2604]

That's because, in the RouteProps interface, the component is defined as optional, hence it might be undefined.

export interface RouteProps {
  location?: H.Location;
  component?: React.ComponentType<RouteComponentProps<any>> | React.ComponentType<any>;
  render?: ((props: RouteComponentProps<any>) => React.ReactNode);
  children?: ((props: RouteChildrenProps<any>) => React.ReactNode) | React.ReactNode;
  path?: string | string[];
  exact?: boolean;
  sensitive?: boolean;
  strict?: boolean;
}

Simply check for if the component is falsy will fix it.

function PrivateRoute({ component: Component, ...rest }: RouteProps) {
  if (!Component) return null;
  return (
    <Route
      {...rest}
      render={props =>
        fakeAuth.isAuthenticated ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/login",
              state: { from: props.location }
            }}
          />
        )
      }
    />
  );
}



回答3:


Even later to the party, but what worked for me is this:

interface PrivateRouteProps extends Omit<RouteProps, "component"> {
  component: React.ElementType;
  // any additional vars
}

PrivateRoute: React.FC<PrivateRouteProps> = ({
  component: Component,
  ...rest
}) => {
// render code
}


来源:https://stackoverflow.com/questions/53452966/typescript-3-jsx-element-type-component-does-not-have-any-construct-or-call-s

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!