You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript下如何为React中withRouter传入的history对象添加类型检查?

为withRouter包装的子组件的history props添加类型检查的规范实现

我来给你讲讲两种主流场景下的规范实现方式,对应不同的技术栈:

一、TypeScript 项目(推荐,React Router官方支持)

React Router 已经为我们提供了现成的类型定义,直接用官方类型就能保证准确性,不用自己手动拼凑结构。

方法1:使用 RouteComponentProps 完整类型

这个类型包含了 history、location、match 这三个由 withRouter 注入的props,适合需要用到多个路由相关props的场景:

import { RouteComponentProps, withRouter } from 'react-router-dom';
import styles from './ChildComponent.module.css';
import FloatingActionButton from './FloatingActionButton';
import routes from './routes';

// 定义组件props类型
type ChildComponentProps = RouteComponentProps;

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

export default withRouter(ChildComponent);

方法2:只提取 history 属性(更精准)

如果你的组件只用到 history,不需要其他路由props,可以用 Pick 工具类型只提取需要的部分:

import { RouteComponentProps, withRouter } from 'react-router-dom';
import styles from './ChildComponent.module.css';
import FloatingActionButton from './FloatingActionButton';
import routes from './routes';

// 只保留history属性
type ChildComponentProps = Pick<RouteComponentProps, 'history'>;

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

export default withRouter(ChildComponent);

方法3:直接使用 History 类型

也可以单独导入 History 类型来定义props:

import { History, withRouter } from 'react-router-dom';
import styles from './ChildComponent.module.css';
import FloatingActionButton from './FloatingActionButton';
import routes from './routes';

type ChildComponentProps = {
  history: History;
};

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

export default withRouter(ChildComponent);

二、JavaScript 项目(使用 PropTypes)

如果你的项目还在使用纯JavaScript,可以通过 PropTypes 来做运行时的类型检查,只需要定义你实际用到的方法即可:

import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import styles from './ChildComponent.module.css';
import FloatingActionButton from './FloatingActionButton';
import routes from './routes';

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类型检查规则
ChildComponent.propTypes = {
  history: PropTypes.shape({
    push: PropTypes.func.isRequired, // 你用到的push方法必须是函数且必填
    // 如果后续用到其他方法,比如replace、goBack,可以按需添加
    replace: PropTypes.func,
    goBack: PropTypes.func,
  }).isRequired,
};

export default withRouter(ChildComponent);

简单总结下:TypeScript场景优先用官方提供的类型,既规范又能获得完整的类型提示;JavaScript场景用PropTypes做运行时校验,只定义用到的属性即可,不用冗余定义整个history对象的所有方法。

内容的提问来源于stack exchange,提问作者Ivin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:27:58