我有下面一段代码,它接收一个历史对象作为props :

const ChildComponent = ({ history }) => (
        <div className={styles.body}>
            <div className={styles.cta}>
                <FloatingActionButton onClick={() => history.push(routes[4].path)}>
                    <span>Click me</span>
                </FloatingActionButton>
            </div>
        </div>
);

如何为这个历史props which is received by wrapping it's parent with withRouter HOC添加类型判断?我能想到的一种方法是写这样的东西:

interface Props {
    history: {
        push(url: string): void;
    };
}

但我确信这不是正确的方法,因为历史对象的其他属性正在丢失.

你能建议正确的方法吗?

UPDATED the code based on @Oblosys's answer

import { withRouter, RouteComponentProps } from "react-router-dom";

interface Props extends RouteComponentProps<any> {
   /* Parent component's props*/
}

class Parent extends React.Component<Props, {}> {
    render() {
        return <ChildComponent history={this.props.history} />;
    }
}

//Child component related stuff
interface ChildComponentProps extends RouteComponentProps<any> {}

const ChildComponent: React.SFC<ChildComponentProps> = (props) => (
  <div className={styles.body}>
     <div className={styles.cta}>
         <FloatingActionButton onClick={() => history.push(routes[4].path)}>
            <span>Click me</span>
         </FloatingActionButton>
     </div>
   </div>
);

function mapStateToProps(state: types.AppState) {
    /* related code */
}

function mapDispatchToProps(dispatch: Redux.Dispatch<types.AppState>{
    /* related code */
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Parent));

但是,现在我得到了以下错误:

Type '{ history: History; }' is not assignable to type 'ChildComponentProps'.
    Property 'match' is missing in type '{ history: History; }'

推荐答案

您可以使用RouteComponentProps接口,该接口声明withRouter传递的所有props :

import { RouteComponentProps } from 'react-router-dom';
..
interface ChildComponentProps extends RouteComponentProps<any> {
  /* other props for ChildComponent */
}
const ChildComponent : React.SFC<ChildComponentProps> = ({ history }) => (
  ..
);

RouteComponentProps的type参数是matchparams属性的类型,因此除非匹配命名路径段,否则不需要它.

或者,如果history不是来自withRouter,而是作为props 自行传递,则可以从history导入类型:

import { History } from 'history';
..
interface ChildComponentProps {
  history : History
  /* other props for ChildComponent */
}
const ChildComponent : React.SFC<ChildComponentProps> = ({ history }) => (
  ..
);

Typescript相关问答推荐

通用默认值触发依赖通用约束变量的错误

错误:note_modules/@types/note/globals.d.ts:72:13 -错误TS 2403:后续变量声明必须具有相同的类型

VS代码1.88.0中未出现自动导入建议

TypeScript类型不匹配:在返回类型中处理已经声明的Promise Wrapper

类型脚本`Return;`vs`Return unfined;`

向NextAuth会话添加除名称、图像和ID之外的更多详细信息

在实现自定义主题后,Angular 不会更新视图

有没有可能为这样的函数写一个类型?

MatTool提示在角垫工作台中不起作用

保护函数调用,以便深度嵌套的对象具有必须与同级属性函数cargument的类型匹配的键

刷新时保持当前名称的Angular

在React中定义props 的不同方式.FunctionalComponent

如何按属性或数字数组汇总对象数组

Typescript 中相同类型的不同结果

如何避免从引用<;字符串&>到引用<;字符串|未定义&>;的不安全赋值?

如何解决&Quot;类型不可分配给TypeScrip IF语句中的类型&Quot;?

是否可以在类型脚本中定义条件返回类型,而不在函数体中使用类型转换?

递归生成常量树形 struct 的键控类型

我的类型谓词函数不能像我预期的那样工作.需要帮助了解原因

Angular 16:无法覆盖;baseUrl;在tsconfig.app.json中