说我有这样的代码:
import { Action, Dispatch } from 'redux'; import { ThunkAction } from 'redux-thunk'; interface StateTree { field: string; } function myFunc(action: Action | ThunkAction, dispatch: Dispatch ) { dispatch(action); // <-- This is where the error comes from }
...我从TypeScript编译器中得到此错误:
ERROR in myFile.ts:x:y TS2345: Argument of type 'Action | ThunkAction' is not assignable to parameter of type 'Action'. Type 'ThunkAction ' is not assignable to type 'Action'. Property 'type' is missing in type 'ThunkAction '.
我认为问题是由于redux-thunk
类型定义文件增强了redux
Dispatch
界面的方式以及TypeScript无法知道Dispatch
要使用哪个定义.
有没有解决的办法?
ThunkAction签名随着最新版本(现在是ThunkAction
)而改变,除非有一些邪恶的双重铸造(action as {} as Action
),我发现更优雅的方式是将redux调度定义为ThunkDispatch,如下所示:
import { applyMiddleware, Store, createStore, AnyAction } from 'redux'; import logger from 'redux-logger'; import thunk, { ThunkDispatch } from 'redux-thunk'; import { Redux } from '../definitions'; import rootReducer from './reducers'; import { bootstrap } from './actions'; export default function configureStore() { const middleware = applyMiddleware( thunk, logger ); const store: Store= createStore(rootReducer, middleware); // Here the dispatch casting: (store.dispatch as ThunkDispatch )( bootstrap() ); return store; }
万一其他人正在寻找更新的答案!^^
自从这个问题和各种答案发布以来,时间已经过去,许多事情已经改变。但是,我发现所有答案都不令我满意,因为前两个(迈克尔·佩珀和皮尔皮托姆)涉及重铸/重新定义,这听起来很奇怪。第三个(joaoguerravieira)似乎更好,因为它没有涉及到任何一个,但是至少对我而言,目前尚不清楚如何解决问题。
当我遇到一个实际上与之相同的问题时,这对我似乎最有帮助:如何在创建的redux存储上获取正确类型的“ dispatch”方法。也就是说,如何使TypeScript编译器同意store.dispatch可以调度Action 或 ThunkActions。即使这与原始问题中提出的问题不完全相同(但我认为可能是),所有有关我问题的搜索引擎查询仍将我带回到这篇文章,因此我认为提出解决方案可能会有所帮助这里。
我总是发现在使用redux时很难找到合适的类型来使用东西(也许我只是傻瓜),所以很长一段时间以来我总是这样创建商店:
createStore( combineReducers(stuff), defaultState, applyMiddleware(thunkMiddleware));
...这总是使我处于可以对thunk调用store.dispatch的情况,但是TypeScript编译器对我大吼大叫,尽管它仍然可以在运行时运行。每个答案的点点滴滴最终使我想到了我认为是解决问题的最新方法。
在store对象上分配方法的类型取决于对redux的createStore的调用返回什么。为了在商店的dispatch方法上具有正确的类型,必须在对applyMiddleware的调用上正确设置类型参数(您可以直接或最终将其作为第三个参数传递给createStore)。@joaoguerravieira的回答使我朝这个方向看。为了使调度方法具有正确的类型来调度ThunkAction或Action,我必须这样调用createStore / applyMiddleware:
createStore( combineReducers(stuff), defaultState, applyMiddleware(thunkMiddleware));
哪里
type DispatchFunctionType = ThunkDispatch
通过这样做,我得到了这种类型的商店:
Store> & { dispatch: DispatchFunctionType };
...这使我得到了这种类型的store.dispatch函数:
Dispatch> & ThunkDispatch
...它可以成功调度Action或ThunkAction,而无需大喊类型,也无需任何重新定义/发布。
在对applyMiddleware的调用上正确设置类型参数至关重要!
这些是正确的输入:https : //github.com/reduxjs/redux-thunk/blob/master/test/typescript.ts
最为显着地:
const store = createStore(fakeReducer, applyMiddleware(thunk as ThunkMiddleware));
applyMiddleware
将已经用覆盖了调度ThunkDispatch
。