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.
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 }
}}
/>
)
}
/>
);
}