如何在 React 中添加历史对象的类型检查?

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

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>
);

如何为这个历史道具 它是通过用路由器 HOC 包装它的父节点来接收的添加类型检查?我能想到的一个办法就是这样写:

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

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

你能提出正确的做法吗?

根据@Oblosys 的回答更新了代码

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; }'
80813 次浏览

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

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,而是作为道具传递给它自己,你可以从 history导入类型:

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

对于带钩子的反应16.8:

...
import {withRouter, RouteComponentProps} from 'react-router-dom';
...
const ChildComponent: React.FunctionComponent<RouteComponentProps> = ({history}) => {
...
}

我找到的最简单的解决办法

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


....


interface Foo{
history: RouteComponentProps["history"];
location: RouteComponentProps['location'];
match: RouteComponentProps['match'];
}