使用TypeScript时React Redux connect出现调用签名错误
我在编写React组件时,使用react-redux的高阶函数connect遇到了TypeScript错误,代码如下:
import React, {Component} from 'react'; import connect from 'react-redux' import {ExperimentsState, Root} from "../../types/somepath.redux"; import {Dispatch} from "redux"; import experimentActions from "../../redux/actions/experimentActions"; type StateToProps = { experiments: ExperimentsState; }; type DispatchToProps = { fetchExperiments(): () => void; } type SignalsHomePageContainerProps = StateToProps & DispatchToProps class SignalsHomePageContainer extends Component<SignalsHomePageContainerProps, ExperimentsState> { render() { return ( <div> Hi, I am container </div> ); } } const mapStateToProps = (state: Root) => ({ experiments: state.experiments.data }) const mapDispatchToProps = (dispatch: Dispatch) => ({ fetchExperiments: () => dispatch(experimentActions.fetchExperiments()) }) export default connect<StateToProps, DispatchToProps>(mapStateToProps, mapDispatchToProps)(SignalsHomePageContainer);
遇到的错误:
TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'typeof import("somepath/node_modules/@types/react-redux/index")' has no compatible call signatures.
问题修复
核心错误:connect导入方式错误
react-redux中的connect是具名导出,不是默认导出。当前默认导入import connect from 'react-redux'会拿到整个模块对象,而非connect函数本身,这是报错的根本原因。
修复代码:import { connect } from 'react-redux'辅助错误:DispatchToProps类型定义偏差
你定义的fetchExperiments(): () => void表示该方法返回一个无参无返回值的函数,但实际dispatch(experimentActions.fetchExperiments())返回的是action对象(或异步action的返回值),类型不匹配。
修复方案(二选一):// 方案1:自动推导action返回类型 type DispatchToProps = { fetchExperiments: () => ReturnType<typeof experimentActions.fetchExperiments>; } // 方案2:简化类型(无需精确类型时使用) type DispatchToProps = { fetchExperiments: () => void; }可选优化:补全connect泛型参数
若使用的react-redux版本要求完整泛型参数,connect的泛型顺序为connect<StateProps, DispatchProps, OwnProps, RootState>,组件无自定义OwnProps时可传{}:export default connect<StateToProps, DispatchToProps, {}, Root>(mapStateToProps, mapDispatchToProps)(SignalsHomePageContainer);
内容的提问来源于stack exchange,提问作者Altaf

