Anton
Anton

Reputation: 239

route.component does not have any construct or call signatures - React Router with TypeScript

Routes are built from a list of objects. But typescript is highlighting the error:

(property) IRoute.component: React.ReactNode JSX element type 'route.component' does not have any construct or call signatures.

In pure JavaScript, everything works great. How to fix the TypeScript error?

import React from 'react'
import {
  HashRouter as Router,
  Route,
  Switch,
  Redirect,
  RouteComponentProps,
} from 'react-router-dom'

import { ReduxType } from '../container/Container'
import ThemeWrapper from './ThemeWrapper'
import ErrorWrapper from './ErrorWrapper'
import NotifyWrapper from './NotifyWrapper'
import mainPage from './mainLayout/views/Page'
import requestsPage from './requestsLayout/views/Page'
import palettePage from './paletteLayout/views/Page'

interface IRoute {
  key?: number
  path: string
  component: React.ReactNode
  exact: boolean
}

interface IRouteList extends Array<IRoute> {}

const routeList: IRouteList = [
  // {path: '', component: React.ReactNode, [exact]}
  { path: '/', component: mainPage, exact: true },
  { path: '/requests', component: requestsPage, exact: true },
  { path: '/palette', component: palettePage, exact: true },
]

//const AppRouter = (): JSX.Element => {
class AppRouter extends React.Component<ReduxType, any> {
  public render() {
    console.log('AppRouter:' + JSON.stringify(this.props))
    return (
      <ThemeWrapper palette={this.props.palette}>
        <ErrorWrapper>
          <NotifyWrapper>
            <Router>
              <Switch>
                {routeList.map((route, i) => (
                  <Route
                    key={i}
                    render={(props: RouteComponentProps<{}>) => (
                      <route.component {...this.props} />
                    )}
                    path={route.path}
                    exact={route.exact}
                  />
                ))}
                <Redirect to="/" />
              </Switch>
            </Router>
          </NotifyWrapper>
        </ErrorWrapper>
      </ThemeWrapper>
    )
  }
}

export default AppRouter

Upvotes: 2

Views: 1415

Answers (1)

Ajeet Shah
Ajeet Shah

Reputation: 19863

You should use ComponentType for defining React component types instead of ReactNode.

interface IRoute {
  key?: number
  path: string
  component: React.ComponentType // HERE
  exact: boolean
}

Below is the definition of ReactNode:

type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;

which is much suitable for being used for react "children".


And, here is ComponentType:

type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;

which is specially for components - function and class.


The error:

XYZ does not have any construct or call signatures

Above error is trying to hint you that current type i.e. "ReactNode" doesn't have a "constructor" which is required (and present) in React Components (ComponentType).

Here is a good React-TypeScript cheatsheet: https://github.com/typescript-cheatsheets/react

Upvotes: 2

Related Questions