如何将 Redux 4.0 TypeScript 绑定与 redux-thunk 一起使用

Posted

技术标签:

【中文标题】如何将 Redux 4.0 TypeScript 绑定与 redux-thunk 一起使用【英文标题】:How to use Redux 4.0 TypeScript bindings with redux-thunk 【发布时间】:2018-11-09 21:34:10 【问题描述】:

我在使用带有 redux-thunk 的 Redux 4.0 的新 TS 绑定时遇到问题。我通过将基本的 Redux "Todo List" example 转换为 TypeScript (repo here) 重新创建了这个问题,并使 Add Todo 操作成为一个 thunk。问题与报告的here 相同:“ThunkAction”类型的参数不可分配给“AnyAction”类型的参数。 类型“ThunkAction”中缺少属性“类型”

基本上,我可以让它工作,但我在几个我认为不应该使用的地方使用any。一个地方是index.tsx#L14,我把thunk中间件加到store里面:

const store = createStore(
  rootReducer,
  applyMiddleware(thunk as ThunkMiddleware<IRootState, any>)
);

如果我在那里使用any 以外的任何东西,那么下一行将引发错误:

store.dispatch(addTodo('Use redux-thunk'));

另一个地方是AddTodo.tsx#L7,在这里我声明了由connect函数注入的dispatch prop:

interface IAddTodoProps 
  dispatch: Dispatch<any>;


const AddTodo = ( dispatch : IAddTodoProps) => 
  ...

export default connect()(AddTodo);

在这两个地方,any 覆盖了必须扩展 Action&lt;any&gt; 的类型。 Action 需要 type 属性,当然 thunk 没有。如何声明这些类型以便 dispatch 函数接受 thunk?

Related questionRelevant PR

【问题讨论】:

【参考方案1】:
diff --git a/src/containers/AddTodo.tsx b/src/containers/AddTodo.tsx
index e49ac4a..20a93d6 100644
--- a/src/containers/AddTodo.tsx
+++ b/src/containers/AddTodo.tsx
@@ -1,10 +1,12 @@
 import * as React from 'react';
 import  connect  from 'react-redux';
-import  Dispatch  from 'redux';
+import  ThunkDispatch  from 'redux-thunk';
+import  AnyAction  from 'redux';
 import  addTodo  from '../actions';
+import  IRootState  from '../reducers/index';

 interface IAddTodoProps 
-  dispatch: Dispatch<any>;
+  dispatch: ThunkDispatch<IRootState,any,AnyAction>;
 

 const AddTodo = ( dispatch : IAddTodoProps) => 

【讨论】:

谢谢,但这并不能真正摆脱anys【参考方案2】:

这个问题(以及许多其他问题)的答案原来是:使用Redux Toolkit。

商店设置非常简单:

// src/redux/store.ts
import  configureStore  from '@reduxjs/toolkit';
import reducer from './reducers';

const store = configureStore( reducer );

export type AppDispatch = typeof store.dispatch;

export default store;

然后在使用react-redux 中的useDispatch 挂钩时,只需键入AppDispatch

// src/components/App.tsx
import  useDispatch  from 'react-redux';
import  AppDispatch  from '../redux/store';

const App = () => 
  const dispatch: AppDispatch = useDispatch();
  // ...

【讨论】:

以上是关于如何将 Redux 4.0 TypeScript 绑定与 redux-thunk 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

如何在 TypeScript 中键入 Redux 操作和 Redux reducer?

如何使用 typescript、next-redux-wrapper、getServerSideProps?

使用 typescript 将异步操作发送到 redux 调度

将 Typescript 与 React-Redux 一起使用时出现类型错误

将 React Redux 连接到 Typescript 中的组件

如何在TypeScript中实现redux中间件类