2

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

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

1 Comment

Many thanks. Your answer helped fix the error

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.