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.
The error "JSX element type does not have any construct or call signatures" occurs when we try to pass an element or a react component as props to another component but type the prop incorrectly. To solve the error, use the React. ElementType type.
What is JSX? JSX stands for JavaScript XML. JSX allows us to write HTML in React. JSX makes it easier to write and add HTML in React.
React. cloneElement() is part of the React Top-Level API used to manipulate elements. It clones and returns a new element using its first argument as the starting point. This argument can be a React element or a component that renders a React element.
A React node is defined as: a light, stateless, immutable, virtual representation of a DOM node. React nodes are not real DOM nodes (e.g., text or element nodes) themselves, but a representation of a potential DOM node. The representation is considered the virtual DOM.
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 } }} /> ) } /> ); }
I have encountered this a couple of times. Try these:
PrivateRoute
as React.FC<Props>
React.ElementType
The ultimate truth about React types comes from the docs
Edit: React.ReactType (deprecated) -> React.ElementType
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With