我应该为对象休息道具声明什么类型?

use*_*776 5 typescript reactjs react-router

以下是 react-router 的一个示例,用于说明如何为受保护的路由添加组件:

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

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

我试图在我的 Typescript 项目中实现这个功能,使用上面的例子作为灵感。

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;
Run Code Online (Sandbox Code Playgroud)

我收到以下错误

[ts] Cannot find name 'rest'.
any

[ts] JSX element type 'Component' does not have any construct or call signatures.
const Component: React.Component<{}, {}, any>
Run Code Online (Sandbox Code Playgroud)

Ric*_*ard 7

1)您还没有从解构运算符中提取剩余的道具,要获取其余的道具,您需要以下内容:

const { component: Component, isSignedIn, location, ...rest } = props;
Run Code Online (Sandbox Code Playgroud)

2)Component不是你想象的那样,它是类元素构造的接口,但你用它来定义类型。如果您希望将其作为元素强制执行,则需要使用JSX.Element.

最终你应该留下:

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;
Run Code Online (Sandbox Code Playgroud)