1

I am working on a project using TypeScript, React and Redux. Currently I came across the issue that I want to route a user that is not authenticated directly to a login page, otherwise to the content page.

My main problem is that I receive a TypeScript compile error, because I cannot figure out the right type definitions for the Route components. I checked on several tutorials online, whereas I cannot manage to port their code and get it working with my example.

Here is my index.tsx:

import * as React from 'react';
import * as ReactDOM from 'react-dom';

import { Router, Route } from 'react-router';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, combineReducers } from 'redux';
import { routerReducer, routerMiddleware } from 'react-router-redux';
import { Reducers, InitialState } from './reducers';

import thunk from 'redux-thunk';
import createHistory from 'history/createBrowserHistory';

import App from './app/App';
import Content from './components/pages/Content';
import Login from './components/pages/Login';
import Overview from './components/containers/Overview';
import Payment from './components/containers/Payment';
import Profile from './components/containers/Profile';

const history = createHistory();    
const middleware = routerMiddleware(history);

const store = createStore(
  combineReducers({
    ...Reducers,
    router: routerReducer
  }),
  InitialState,
  applyMiddleware(thunk.withExtraArgument(middleware)),
);

function isAuth() {
  let user = FirebaseApp.auth().currentUser;
  return user !== null;
}

const app = document.getElementById('root') as HTMLElement;
ReactDOM.render(
  <Provider store={store}>
    <Router history={history}>
      <Route component={App}>
        <Route path="/" component={Content}>
          <Route path="/" exact={true} component={Overview} />
          <Route path="/payment" component={Payment} />
          <Route path="/profile" component={Profile} />
        </Route>
        <Route onEnter={isAuth}>
          <Route component={Login} />
        </Route>
      </Route>
    </Router>
  </Provider>,
  app
);

The IDE is showing errors at the following lines: IDE shows error and the compiler throws the following error: Failed to compile.

./src/index.tsx
(60,14): error TS2322: Type '{ component: ComponentClass<{}>; children: Element[]; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Route> & Readonly<{ children?: ReactNode; }> & Rea...'.
  Type '{ component: ComponentClass<{}>; children: Element[]; }' is not assignable to type 'Readonly<RouteProps>'.
    Types of property 'component' are incompatible.
      Type 'ComponentClass<{}>' is not assignable to type 'StatelessComponent<RouteComponentProps<any> | undefined> | ComponentClass<RouteComponentProps<any...'.
        Type 'ComponentClass<{}>' is not assignable to type 'ComponentClass<RouteComponentProps<any> | undefined>'.

See also the App, Content and one of the page (e.g. Profile) definitions:

// App:
import * as React from 'react';
import './App.css';
import { connect } from 'react-redux';
import { GlobalState } from '../reducers';
export class App extends React.Component<any, any> {
  render() {
    return (
      <div id="viewport" className="App" />
    );
  }
}
function select(state: GlobalState) {
  return state.sessionState;
}
export default connect(select)(App);

// Content:
import * as React from 'react';
import { RouteComponentProps } from 'react-router';
import Header from '../header/Header';
import Footer from '../footer/Footer';
export default class Content extends 
React.Component<RouteComponentProps<{}>, void> {
    render() {
        return (
            <div>
                <Header />
                <div className="Layout" id="container" />
                <Footer />
            </div>
        );
    }
}

// Login:
import * as React from 'react';
import { RouteComponentProps } from 'react-router';
export default class Login extends React.Component<RouteComponentProps<{}>, void> {
    render() {
        return (
            <div>
                <input type="email" value="" />
                <input type="password" value="" />
                <input type="submit" value="Login" />
            </div>
        );
    }
}

// Profile:
import * as React from 'react';
import { RouteComponentProps } from 'react-router';
export default class Profile extends React.Component<RouteComponentProps<{}>, void> {
    render() {
        return (
            <div>
                Profile
            </div>
        );
    }
}

I tried to base my implementation on the following GitHub repository dictionary-react-redux-typescript

0

1 Answer 1

3

I think that this is the same issue as I have asked a question for. Here it is. I believe it got fixed so try updating your "@types/react-router" package.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.