Typescript:如何在 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>
);

如何为这个历史道具添加类型检查, 它是通过用 withRouter 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; }'

原文由 Ivin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 524
2 个回答

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

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

--- 的类型参数是 RouteComponentProps 中的 match params 属性的类型,因此除非匹配命名路径段,否则不需要它。

或者,如果 history 不是来自 withRouter 而是作为道具本身传递,您可以从 history 导入类型:

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

原文由 Oblosys 发布,翻译遵循 CC BY-SA 3.0 许可协议

我找到的最简单的解决方案

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

....

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

原文由 Siddharth 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进