如何在Redux 4.0 TypeScript绑定中正确使用redux-thunk
搞定Redux 4.0 + TypeScript + redux-thunk的类型不兼容问题
嘿,我完全懂你遇到的这个痛点——redux-thunk的函数本身不是标准Redux Action(缺type属性),默认的Dispatch类型根本不认它,只能用any凑活,太难受了。下面给你一套不用any的完整解决方案:
1. 先定义好全局的Thunk类型
首先我们要在项目里统一类型,比如新建一个src/types/redux.ts文件,把核心的Thunk相关类型都定好:
import { ThunkAction, ThunkDispatch } from 'redux-thunk'; import { Action, AnyAction } from 'redux'; import { IRootState } from '../reducers'; // 这里替换成你自己的RootState类型 // 定义项目专属的ThunkAction类型,统一参数 export type AppThunk<ReturnType = void> = ThunkAction< ReturnType, IRootState, unknown, // 如果你的thunk需要额外注入参数,这里可以改,没有就用unknown Action<string> >; // 定义支持Thunk的Dispatch类型,这个是关键! export type AppDispatch = ThunkDispatch<IRootState, unknown, AnyAction>;
2. 配置Store时用正确的中间件类型
在创建Store的文件(比如src/index.tsx)里,不用再把thunk强转成any了,直接用我们定义的类型:
import { createStore, applyMiddleware } from 'redux'; import thunk, { ThunkMiddleware } from 'redux-thunk'; import rootReducer from './reducers'; import { IRootState } from './reducers'; const store = createStore( rootReducer, applyMiddleware( thunk as ThunkMiddleware<IRootState, AnyAction> ) ); // 导出Store的类型,方便后续组件使用 export type AppStore = typeof store; // 这里的dispatch类型已经自动是支持Thunk的AppDispatch了 export type AppDispatch = typeof store.dispatch;
现在你再调用store.dispatch(addTodo('Use redux-thunk')),类型检查就完全通过了,不用再靠any蒙混过关。
3. 组件里的Dispatch类型替换
在AddTodo.tsx里,把原来的Dispatch<any>换成我们定义的AppDispatch:
import { connect } from 'react-redux'; import { AppDispatch } from '../types/redux'; import { addTodo } from '../actions'; interface IAddTodoProps { dispatch: AppDispatch; } const AddTodo = ({ dispatch }: IAddTodoProps) => { // 你的组件逻辑,比如点击按钮调用dispatch(addTodo(inputValue)) }; export default connect()(AddTodo);
更推荐的做法是用mapDispatchToProps绑定action,连dispatch都不用显式声明,类型还能自动推导:
import { connect, ConnectedProps } from 'react-redux'; import { addTodo } from '../actions'; // 直接把action传进去,connect会自动处理dispatch const mapDispatch = { addTodo }; const connector = connect(null, mapDispatch); // 自动推导从Redux来的props类型 type PropsFromRedux = ConnectedProps<typeof connector>; const AddTodo = ({ addTodo }: PropsFromRedux) => { // 直接调用addTodo(text)就行,类型完全正确 }; export default connector(AddTodo);
这种写法更干净,还能避免手动写类型出错。
最后:给Thunk Action加上正确的类型
你的addTodo这个thunk action也要用我们定义的AppThunk类型,比如:
import { AppThunk } from '../types/redux'; import { ADD_TODO } from './actionTypes'; export const addTodo = (text: string): AppThunk => (dispatch) => { dispatch({ type: ADD_TODO, payload: text }); };
这样整个链路的类型就完全打通了,再也不用依赖any来绕过类型检查。
内容的提问来源于stack exchange,提问作者Jake Boone
相关产品推荐
相关产品推荐

