11

I'm attempting to port a small react app over to typescript.

I'm encountering issues with react-router. I have the latest definitions from definitely type but the following code gives me errors:

var routes:Router.Route = (
<Route name="root" path="/" handler={MyApp}>
  <Route path="dashboard" handler={MyDash} />
  <DefaultRoute handler={SomeSection} />
  <NotFoundRoute handler={NotFoundPage} />
</Route>
);

Router.run(routes, function (Handler:React.Component<any, any>) {
  React.render(<Handler/>, document.body);
});

These are the compilation errors I get:

js/app.tsx(31,3): error TS2605: JSX element type 'Component<RouteProp, any>' is not a constructor function for JSX elements.
  Property 'render' is missing in type 'Component<RouteProp, any>'.
js/app.tsx(32,5): error TS2605: JSX element type 'Component<RouteProp, any>' is not a constructor function for JSX elements.
js/app.tsx(47,5): error TS2605: JSX element type 'Component<DefaultRouteProp, any>' is not a constructor function for JSX elements.
  Property 'render' is missing in type 'Component<DefaultRouteProp, any>'.
js/app.tsx(49,5): error TS2605: JSX element type 'Component<NotFoundRouteProp, any>' is not a constructor function for JSX elements.
  Property 'render' is missing in type 'Component<NotFoundRouteProp, any>'.
js/app.tsx(53,20): error TS2345: Argument of type '(Handler: Component<any, any>) => void' is not assignable to parameter of type '(Handler: RouteClass, state: RouterState) => void'.
  Types of parameters 'Handler' and 'Handler' are incompatible.
    Type 'Component<any, any>' is not assignable to type 'RouteClass'.
js/app.tsx(54,17): error TS2604: JSX element type 'Handler' does not have any construct or call signatures.

What is the correct way to initialize a set of react-router routes using typescript?

(I should clarify that I'm using a nightly typescript build which has support for JSX via the --jsx react flag

1
  • 1
    I had the same issue and it may be a problem with TypeScript's TSX support: Typescript/3928. I asked a similar question there, and they re-opened the issue. Commented Aug 3, 2015 at 21:00

3 Answers 3

15
+150

The root problem was some definitions in react-router not having an explicit render() method. This has been fixed (indirectly) by https://github.com/borisyankov/DefinitelyTyped/pull/5197

Note that this code is incorrect:

Router.run(routes, function (Handler:React.Component<any, any>) {
  React.render(<Handler/>, document.body);
});

It should be:

Router.run(routes, function (Handler: new() => React.Component<any, any>) {
  React.render(<Handler/>, document.body);
});

Because Handler is a constructor for a React component, not an instance of it.

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

1 Comment

Well, not free, since he had to spend time on the answer after all ;)
0

Errors in the type definitions appears to be the cause. You can work around them by modifying the .d.ts files as follows:

In react.d.ts, remove render from the JSX.ElementClass interface

interface ElementClass extends React.Component<any, any> {
}

In react-router.d.ts, change run method's routes parameter's type to React.ReactElement<RouteProp>

function run(routes: React.ReactElement<RouteProp>, callback: RouterRunCallback): Router;
function run(routes: React.ReactElement<RouteProp>, location: LocationBase, callback: RouterRunCallback): Router;

1 Comment

Thanks for answering, but I'm not in love with the idea of changing the .d.ts files. There must be a way to make them work as is otherwise people wouldn't have published them to definitielyTyped.
-1

For making it running under typescript 1.6 with react-router, I've added the following code in the react-router.d.ts file :

interface RouterClass extends React.ComponentClass<any> {}

var Router: RouterClass;

//For Router

function createElement(

type: ReactRouter.RouterClass,

props: any,

...children: __React.ReactNode[]): ReactRouter.Router;

}

interface RouteProp {
    name?: string;
    path?: string;
    handler?: React.ComponentClass<any>;
    ignoreScrollBehavior?: boolean;
    component?: React.ComponentClass<any>;
}

1 Comment

Works fine after applying your changes.

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.