TypeScript React:RouteComponentProps 类型错误或无法访问历史记录

Bil*_*ill 7 typescript reactjs react-router-v4

我制作了一个组件并将其用作...

<TopNav
    loggedIn={global.shared.loggedIn} // false 
    fullName={global.shared.fullName} // ''
    avatar={global.shared.avatarId} // ''
/>
Run Code Online (Sandbox Code Playgroud)

在 TopNav 组件中,我希望能够访问我传入的道具和/props.history或以编程方式导航用户的其他方式而无需刷新..

import React from 'react';
import { RouteComponentProps } from 'react-router-dom';


interface PropsInterfaceNew {
  avatar: string;
  loggedIn: boolean;
  fullName: string;
}

interface PropsInterface
  extends RouteComponentProps<PropsInterfaceNew> {}
//                                    ^ Error

const TopNav: React.FC<PropsInterface> = (props: PropsInterface) => {
...
 const firstName = props.fullName.split(' ')[0]; // I need props.fullName & others
  const search = (event: React.FormEvent) => {
    event.preventDefault();
    props.history.push('/my/profile'); // I need props.history
  };
Run Code Online (Sandbox Code Playgroud)

错误是

Type 'PropsInterfaceNew' does not satisfy the constraint '{ avatar?: string | undefined; loggedIn?: string | undefined; fullName?: string | undefined; }'.
  Types of property 'loggedIn' are incompatible.
    Type 'boolean' is not assignable to type 'string | undefined'.ts(2344)
Run Code Online (Sandbox Code Playgroud)

或者,如果我像下面那样完全删除历史记录,我没有错误但无法访问历史记录

interface PropsInterface {
  avatar: string;
  loggedIn: boolean;
  fullName: string;
}

const TopNav: React.FC<PropsInterface> = (props: PropsInterface) => {
...
Run Code Online (Sandbox Code Playgroud)

@hardik 如果我替换export { TopNav };为...

  export withRouter(TopNav);
//^ err1      ^err2
Run Code Online (Sandbox Code Playgroud)

我得到新的错误 2

statements are not aligned (align)tslint(1)
Run Code Online (Sandbox Code Playgroud)

和错误 1

Declaration or statement expected.ts(1128)
Run Code Online (Sandbox Code Playgroud)

Har*_*ary 5

如果要传递RouteComponentProps,则必须用 包装组件,withRouter然后将其导出。

export withRouter(TopNav);
Run Code Online (Sandbox Code Playgroud)

和道具类型应该是这样的,

interface PropsInterface extends RouteComponentProps {
  avatar: string;
  loggedIn: boolean;
  fullName: string;
}

const TopNav: React.FC<PropsInterface> = (props: PropsInterface) => {....
Run Code Online (Sandbox Code Playgroud)

这绝对可以解决您的问题!


jur*_*ure 4

RouteComponentPropsfrom 接口用于react-router-dom描述路由器将传递给组件 props 的对象。接口的通用参数用于描述“匹配”对象的形状,其中路由器存储所有提取的路由参数的值。

由于路由始终是字符串类型,因此所有匹配的路由参数只能是字符串,因此泛型参数必须是仅具有字符串属性的类型。问题是你的isloggedIn属性是布尔值。为了满足约束,它应该是字符串。

但我不确定这就是你想要的,从你的代码来看fullName,它看起来isLoggedIn不是路由参数,而是显式传递给组件的道具。如果是这种情况,您可以像这样输入 props 对象

interface PropsInterface extends RouteComponentProps {
  avatar: string;
  loggedIn: boolean;
  fullName: string;
}

const TopNav: React.FC<PropsInterface> = (props: PropsInterface) => {....
Run Code Online (Sandbox Code Playgroud)

这使您可以通过键入方式访问所有路由器道具(历史记录、位置、匹配...)以及其他道具。