Búsqueda de sitios web

reactjs - route.component no tiene ningún constructor ni firmas de llamada - React Router con TypeScript


Las rutas se construyen a partir de una lista de objetos. Pero TypeScript está resaltando el error:

(propiedad) IRoute.component: React.ReactNode El tipo de elemento JSX 'route.component' no tiene ninguna firma de construcción o llamada.

En JavaScript puro, todo funciona bien. ¿Cómo solucionar el error de TypeScript?

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

Respuesta #1

Deberías usar ComponentType para definir tipos de componentes de React en lugar de ReactNode.

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

A continuación se muestra la definición de ReactNode:

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

que es mucho más adecuado para ser usado para los "children" de React.


Y, aquí está ComponentType:

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

que es especialmente para componentes - función y clase.


El error:

XYZ no tiene ninguna firma de construcción o llamada

El error anterior intenta indicarte que el tipo actual, es decir, "ReactNode", no tiene un "constructor" que se requiere (y está presente) en los Componentes de React (ComponentType).

Aquí hay una buena hoja de referencia de React-TypeScript: https://github.com/typescript-cheatsheets/react