如何为Redux连接的现有React JSX组件编写TypeScript类型定义文件?
给Redux connect包裹的JSX组件添加TypeScript类型定义
嘿,我来帮你搞定这个问题!给用Redux connect 包裹的JSX组件加TypeScript类型定义,核心是理清组件接收的props来源——从Redux state映射的、组件自身需要的,还有可能的dispatch方法,然后把这些类型明确下来就行。结合你提到的DateField组件例子,我一步步拆解给你看:
1. 先定义完整的Props类型
首先要把不同来源的props类型分开定义,再合并成组件的完整Props类型:
- StateProps:
mapStateToProps返回的props类型,对应从Redux state取到的值 - OwnProps:组件自身接收的外部传入props(Redux不会注入的部分)
- DispatchProps(可选):如果用了
mapDispatchToProps,还要定义这部分的方法类型
以你的DateField为例:
// 从Redux state映射过来的props类型 type DateFieldStateProps = { locale: string; // 这里根据你实际的locale类型调整,比如是'en-US'这类字符串就用string }; // 组件自身接收的外部props(比如你可能需要的label、回调等) type DateFieldOwnProps = { label?: string; onChange?: (selectedDate: Date) => void; }; // 如果有mapDispatchToProps,还要加这个 // type DateFieldDispatchProps = { // updateDate: (date: Date) => void; // }; // 合并成组件的完整Props类型 type DateFieldProps = DateFieldStateProps & DateFieldOwnProps; // 如果有DispatchProps就改成:DateFieldStateProps & DateFieldOwnProps & DateFieldDispatchProps;
2. 给JSX组件添加类型声明
有两种方式可以给现有JSX组件加类型:
方式一:在原JS文件中用JSDoc声明
如果以后打算逐步把JS组件迁移到TS,直接在原JS文件里加JSDoc类型注释是个不错的选择:
/** * @typedef {Object} DateFieldStateProps * @property {string} locale - 从Redux state获取的语言环境 * * @typedef {Object} DateFieldOwnProps * @property {string} [label] - 输入框标签 * @property {(selectedDate: Date) => void} [onChange] - 日期变化回调 * * @typedef {DateFieldStateProps & DateFieldOwnProps} DateFieldProps */ import React from 'react'; import { connect } from 'react-redux'; class DateField extends React.Component { // 你的组件原有逻辑... render() { const { locale, label, onChange } = this.props; // ... } } function mapStateToProps(state) { return { locale: state.systemUser.locale }; } // 如果有mapDispatchToProps,这里要加上 // function mapDispatchToProps(dispatch) { // return { updateDate: (date) => dispatch(updateDateAction(date)) }; // } // 导出connect后的组件 export default connect(mapStateToProps)(DateField);
方式二:单独写.d.ts类型声明文件
如果不想修改原JS文件,可以在同目录下创建一个DateField.d.ts的类型声明文件:
import React from 'react'; import { ConnectedComponent } from 'react-redux'; // 先定义好Props类型(和上面一致) type DateFieldStateProps = { locale: string; }; type DateFieldOwnProps = { label?: string; onChange?: (selectedDate: Date) => void; }; type DateFieldProps = DateFieldStateProps & DateFieldOwnProps; // 声明原始组件类型 declare class DateField extends React.Component<DateFieldProps> {} // 声明connect后的组件类型:ConnectedComponent会帮我们自动处理——外部只需传入OwnProps,StateProps由Redux注入 declare const ConnectedDateField: ConnectedComponent<typeof DateField, DateFieldOwnProps>; export default ConnectedDateField;
3. 在TSX组件中导入使用
现在你在TSX组件里导入DateField时,TypeScript就能自动识别它的props类型了,而且会提示你只需要传入OwnProps的部分(StateProps会由Redux自动注入):
import DateField from './DateField'; function MyTSXComponent() { return ( <div> {/* 这里只需要传label和onChange,locale由Redux注入 */} <DateField label="选择日期" onChange={(date) => console.log('选中日期:', date)} /> </div> ); }
注意事项
- 要确保类型和组件实际使用的props一致,比如如果
locale可能为undefined,那类型要写成locale?: string或者locale: string | undefined,避免TypeScript报错 - 如果你的
mapStateToProps依赖ownProps(比如mapStateToProps(state, ownProps) { ... }),那在定义ConnectedComponent的时候要把这个关联也加上,比如ConnectedComponent<typeof DateField, DateFieldOwnProps, DateFieldStateProps>
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

