如何将Redux 4.0 TypeScript绑定与redux-thunk

时间:2018-05-30 23:33:02

标签: javascript typescript redux react-redux redux-thunk

我在使用带有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中间件添加到商店:

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

如果我使用any以外的任何内容,则下一行会抛出错误:

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

另一个地方是AddTodo.tsx#L7,我在那里声明由connect函数注入的调度道具:

interface IAddTodoProps {
  dispatch: Dispatch<any>;
}

const AddTodo = ({ dispatch }: IAddTodoProps) => {
  ...
}
export default connect()(AddTodo);

在这两个地方,any会覆盖必须延伸Action<any>的类型。 Action需要type属性,当然thunk没有。如何声明这些类型以便dispatch函数接受thunk?

Related question
Relevant PR

2 个答案:

答案 0 :(得分: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) => {

答案 1 :(得分:0)

这个问题(以及许多其他问题)的答案是:使用 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;

然后在使用 useDispatch 中的 react-redux 钩子时,只需将其输入为 AppDispatch

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

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