简体   繁体   中英

react, typescript - a type for both stateless and normal components

I am trying to implement a ProtectedRoute component that has a component prop - which can be a stateless (pure) component or a normal react component.

These are my types:

export interface Props {
  isAuthenticated: boolean;
  component: React.PureComponent | React.Component;
  exact?: boolean;
  path: string;
}

This is my ProtectedRoute component:

import React from 'react';
import { Redirect, Route } from 'react-router-dom';

import { ROUTES } from '../../constants/routes';

import { Props } from './ProtectedRoute.types';

const ProtectedRoute = (props: Props) => {
  const { isAuthenticated, component: Component, ...rest } = props;
  return (
    <Route
      {...rest}
      children={props =>
        !isAuthenticated ? (
          <Redirect to={{ pathname: ROUTES.login, state: { from: props.location } }} />
        ) : (
          <Component {...props} />
        )
      }
    />
  );
};

export default ProtectedRoute;

I am getting the following error here:

Type error: JSX element type 'Component' does not have any construct or call signatures. TS2604

This is how I use it:

import React from 'react';

import { Route, Switch } from 'react-router-dom';
import ProtectedRoute from './ProtectedRoute';

import { ROUTES } from '../../constants/routes';

import Login from '../Login/Login';
const PlaceholderComponent = () => <div>This is where we will put content.</div>;
const NotFoundPlaceholder = () => <div>404 - Route not found.</div>;

const Routes = () => {
  return (
    <Switch>
      <Route exact path={ROUTES.login} component={Login} />
      {/* TODO protected route */}
      <ProtectedRoute exact path={ROUTES.list} component={PlaceholderComponent} />
      <ProtectedRoute exact path={ROUTES.procedure} component={PlaceholderComponent} />
      {/* catchall route for 404 */}
      <Route component={NotFoundPlaceholder} />
    </Switch>
  );
};

export default Routes;

And getting the following error here:

Type '() => Element' is not assignable to type 'PureComponent<{}, {}, any> | Component<{}, {}, any>'. Type '() => Element' is missing the following properties from type 'Component<{}, {}, any>': context, setState, forceUpdate, render, and 3 more. [2322]

This makes me think that I am using the incorrect type definition. What would be the 'correct' way to go about this? My purpose is to check that ProtectedRoute always gets a React component as the component prop.

A type for both functional and class components is ComponentType .

It should be:

export interface Props {
  isAuthenticated: boolean;
  component: React.ComponentType;
  exact?: boolean;
  path: string;
}

Probably found it, but will leave this open, since I do not know if this is the correct solution:

export interface Props {
  isAuthenticated: boolean;
  component: React.ComponentClass<any> | React.StatelessComponent<any>;
  exact?: boolean;
  path: string;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM