4
votes

I'm trying to convert the way an alternate route component is defined in JSX an equivalent TypeScript TSX file. (1)

The JSX syntax is like this:

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

export const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route {...rest} render={props => (
        localStorage.getItem('user')
            ? <Component {...props} />
            : <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
    )} />
)

I've tried to convert it to TypeScript, but in Visual Studio, the <Component part (see below) is underlined and the TypeScript compiler tells me

(TS) JSX element type 'Component' does not have any construct or call signatures.

I don't really understand the ({ component: Component, ...rest }) syntax of the lambda function. This is as far as I've gotten on writing it in TypeScript.

export function PrivateRoute(Component: React.Component, ...rest: any[]) {
    return (
        <Route {...rest} render={props => (
            localStorage.getItem('user')
                ? <Component {...props} />
                : <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
        )} />
    );
};

Any suggestions?

References:

  1. https://www.pointblankdevelopment.com.au/blog/135/react-redux-with-aspnet-core-20-login-registration-tutorial-example#private-route-jsx
1
({ component: Component, ...rest }) means taking a component attribute from the object via destructuring and renaming it to Component in the function scope, and putting the rest of the attributes of the object in a variable named rest through the "rest" operator (the ...). I hope that clears it up, I don't know TS so I can't help you refactor that :)SrThompson
OK that's interesting. Does that syntax have a name I can google or is there any documentation you can point to on it?Erik
The good old MDN documentation has a lot of examples. Note that destructuring and rest/spread operators are available on arrays and objects: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…SrThompson
why dont you use the class syntaxSujit.Warrier
How would that work?Erik

1 Answers

0
votes

Regarding the error - JSX/TSX <Component ... will be converted to something like React.createElement(Component..., so Component type should be a function/class, not an instance. Hence the proper typing for it will be ComponentType.

Regarding { component: Component, ...rest } - this is an object destructuring with assignment to new variable. Passed parameter is unpacked to variables Component and rest (component property of the parameter goes to Component variable and all the rest properties go to rest variable)

To sum up, the resulting typing might look like:

type RouteProps = { component: React.ComponentType };
export function PrivateRoute(
    { component: Component, ...rest }: RouteProps) {
    ...
};