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

时间:2018-11-01 11:47:39

标签: reactjs typescript 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 }
            }}
          />
        )
      }
    />
  );
}

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;

我遇到以下错误

[ts] Cannot find name 'rest'.
any

[ts] JSX element type 'Component' does not have any construct or call signatures.
const Component: React.Component<{}, {}, any>

1 个答案:

答案 0 :(得分:2)

1)您尚未从解构操作员那里提取剩余的道具,要获得其余的道具,您将需要此:

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

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;