reactjs 打字稿:如何在 React 中为历史对象添加类型检查?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49342390/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 04:29:16  来源:igfitidea点击:

Typescript: How to add type check for history object in React?

reactjstypescripttypescript-typings

提问by phoenix

I have the following piece of code, which receives a history object as prop:

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

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

How do I add typecheck for this history prop, which is received by wrapping it's parent with withRouter HOC? One way I could think of is to write something like this:

我如何为这个历史道具添加类型检查,这是通过用 withRouter HOC 包装它的父级来接收的?我能想到的一种方法是写这样的东西:

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

But Im sure this is not the right way, because rest of the properties of the history object are being lost.

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

Can you suggest the right way of doing this?

你能建议这样做的正确方法吗?

UPDATED the code based on @Oblosys's answer

根据@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));

But, now Im getting the following error:

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

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

回答by Oblosys

You can use the RouteComponentPropsinterface, which declares all props passed by withRouter:

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

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

The type parameter to RouteComponentPropsis the type of the paramsproperty in match, so you won't need it unless you're matching named path segments.

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

Alternatively, if historydoesn't come from withRouterbut is passed by itself as a prop, you can import the type from history:

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

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

回答by Andrey Ptashinskiy

For React 16.8 with hooks:

对于带有钩子的 React 16.8:

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