属性“位置”在类型“只读<{}>”上不存在-React Router和Typescript

时间:2019-10-22 15:54:18

标签: reactjs typescript router

我正在尝试创建用于身份验证的受保护路由。我有一个在文档中建议的ProtectedRoute组件,如下所示:

interface ProtectedRouteProps {
  auth: AuthState;
}

const ProtectedRoute = ({
  children,
  auth,
  ...rest
}: RouteProps & ProtectedRouteProps): JSX.Element => {
    console.log(auth)
  return (
    <Route
      {...rest}
      render={(props: RouteProps) =>
        auth.isAuthenticated ? children : <Redirect to={{pathname: "/signin", state: "Please sign in" }} />
      }
    />
  );
};

export default ProtectedRoute;

然后我使用它,如果有人被重定向到登录页面,我想显示状态(“请登录”)。

我有一个处理路由的包装器组件:

export interface IWrapper {
    auth: AuthState
}

class Wrapper extends Component<IWrapper> {
    constructor(props: IWrapper){
        super(props);
        console.log(props)
    }
  render() {

    return (
      <div>
        <BrowserRouter>
          <HeaderContainer />
          <Switch>
          <Route exact path="/">
              <Home />
          </Route>
          <Route exact path="/signup">
            <SignUpView />
          </Route>
          <ProtectedRoute auth={this.props.auth} path="/dashboard">
              <DashboardContainer />
          </ProtectedRoute>
          </Switch>
          <Route exact path="/" component={Home}></Route>
          <Route exact path="/signout" component={SignUpView}></Route>
          <Route exact path="/signin" component={SignIn}></Route>

        </BrowserRouter>
      </div>
    );
  }
}

const mapStateToProps = (state: AppState) => ({
    auth: state.auth
})

export default connect(mapStateToProps)(Wrapper)

这是我的登录页面:

export default class SignIn<RouteComponentProps> extends Component {
    constructor(props: RouteComponentProps){
        super(props);
        console.log(props);
    }


    render() {
        return (
            <div>
                {this.props.location.state ? (
                    <h2>You were redirected</h2>
                ) : ("")}
                <SignInForm />
            </div>
        )
    }
}

打字稿编译器说我无法执行props.location,因为“属性'location'在'Readonly <{}>和Readonly <{children ?: ReactNode;}>'类型上不存在”。

我真的不明白这意味着什么。在RouteComponentProps的类型定义中,您具有:

export interface RouteComponentProps<Params extends { [K in keyof Params]?: string } = {}, C extends StaticContext = StaticContext, S = H.LocationState> {
  history: H.History;
  location: H.Location<S>;
  match: match<Params>;
  staticContext?: C;
}

那是什么问题?我已经尝试过使用重定向道具,但这也不起作用。我是Typescript的n00b,所以如果有人可以帮助我将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:3)

在没有阅读所有代码的情况下,我猜测您可以仅更改SignIn类的定义

export default class SignIn<RouteComponentProps> extends Component { ... }

export default class SignIn extends Component<RouteComponentProps> { ... }

,那么您应该很好。

通常,泛型类型的参数会在类名后加上注释,在您的情况下则不需要。在extends子句具体中,为要扩展的组件设置参数。如果您只写extends Component而未通过Component<RouteComponentProps>指定道具类型,则使用{}的默认类型Component,TS无法找到location属性在普通对象文字{}上。

有关泛型类的更多信息,请参见here