Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What type should I declare for object rest props?

Here is an example from react-router for how to add a component for protected routes:

function PrivateRoute({ component: Component, ...rest }) {
  return (
    <Route
      {...rest}
      render={props =>
        fakeAuth.isAuthenticated ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/login",
              state: { from: props.location }
            }}
          />
        )
      }
    />
  );
}

https://reacttraining.com/react-router/web/example/auth-workflow

I have tried to implement this functionality in my Typescript project, using the example above as inspiration.

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

interface PrivateRouteProps {
    component: React.Component; // passed as prop
    isSignedIn: boolean; // injected as prop by redux
    location: Location;
}

const PrivateRoute = (props: PrivateRouteProps) => {
    const { component: Component, isSignedIn, location } = props;

    return (
        <Route
            {...rest}
            render={(routeProps) =>
                isSignedIn ? (
                    <Component {...routeProps} />
                ) : (
                        <Redirect
                            to={{
                                pathname: '/signin',
                                state: { from: location }
                            }}
                        />
                    )
            }
        />
    );
};

export default PrivateRoute;

I get the following errors

[ts] Cannot find name 'rest'.
any

[ts] JSX element type 'Component' does not have any construct or call signatures.
const Component: React.Component<{}, {}, any>
like image 669
user1283776 Avatar asked Nov 01 '18 11:11

user1283776


People also ask

Which object is used in component to set the type of props?

propTypes = { //// key is the name of the prop and // value is the PropType } export default Count; PropTypes are also objects with a key and a value pair where the 'key' is the name of the prop while the value represents the type or class by which they are defined.

How do you pass objects as props in React?

Use the spread syntax (...) to pass an object as props to a React component, e.g. <Person {... obj} /> . The spread syntax will unpack all of the properties of the object and pass them as props to the specified component. Copied!

Is props are mutable or immutable?

Props are immutable, while state is mutable Although a component is not allowed to change its props, it is responsible for the props of its child components down the component tree. On the other hand, state is mutable. A stateful component changes its state every time users interact with the app.


2 Answers

1) You haven't pulled the remaining props from your destructuring operator, to get the rest of the props, you'll need this:

const { component: Component, isSignedIn, location, ...rest } = props;

2) Component isn't what you think it is here, it is an interface for class element construction, but you're using it to define a type. If you're looking to enforce it as an Element, you'll want to use JSX.Element.

Ultimately you should be left with:

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

interface PrivateRouteProps {
    component: JSX.Element; // passed as prop
    isSignedIn: boolean; // injected as prop by redux
    location: Location;
}

const PrivateRoute = (props: PrivateRouteProps) => {
    const { component, isSignedIn, location, ...rest } = props;

    return (
        <Route
            {...rest}
            render={(routeProps) =>
                isSignedIn ? (
                    <Component {...routeProps} />
                ) : (
                        <Redirect
                            to={{
                                pathname: '/signin',
                                state: { from: location }
                            }}
                        />
                    )
            }
        />
    );
};

export default PrivateRoute;
like image 134
Richard Avatar answered Oct 17 '22 17:10

Richard


import React, { forwardRef, ReactNode } from "react"

interface ICardProps {
    children: ReactNode;
    className?: string;
    [props: string]: any;
}
const Card = forwardRef<HTMLDivElement, ICardProps>(( props, ref ) => {
    const { className, children, ...rest } = props;
    return <div ref={ref} className={className} {...rest}>{children}</div>
})

export default Card;
like image 1
Semih R. Gürel Avatar answered Oct 17 '22 19:10

Semih R. Gürel