假设我有这样的代码:
import { Action, Dispatch } from 'redux';
import { ThunkAction } from 'redux-thunk';
interface StateTree {
field: string;
}
function myFunc(action: Action | ThunkAction<void, StateTree, void>,
dispatch: Dispatch<StateTree>) {
dispatch(action); // <-- This is where the error comes from
}
...I从TypeScript编译器获得此错误:
ERROR in myFile.ts:x:y
TS2345: Argument of type 'Action | ThunkAction<void, StateTree, void>' is not assignable to parameter of type 'Action'.
Type 'ThunkAction<void, StateTree, void>' is not assignable to type 'Action'.
Property 'type' is missing in type 'ThunkAction<void, StateTree, void>'.
我认为问题在于redux-thunk
类型定义文件增强redux
Dispatch
接口的方式,以及TypeScript无法知道使用哪个Dispatch
定义。
有办法绕道吗?
发布于 2017-03-26 02:50:29
我认为你是正确的,尽管能够处理这两种类型,类型记录无法计算出哪种过载使用。
我认为最好的选择是在调用dispatch
时返回到所需的类型
function myFunc(action: Action | ThunkAction<void, StateTree, void>,
dispatch: Dispatch<StateTree>) {
if (action instanceof ThunkAction<void, StateTree, void>) {
dispatch(action as ThunkAction<void, StateTree, void>);
} else {
dispatch(action as Action);
}
}
我希望我错了,有更好的方法来实现这一点。
发布于 2018-06-07 04:43:03
ThunkAction签名随着最新版本(现在是ThunkAction<void, Your.Store.Definition, void, AnyAction>
)而改变,除非有一些邪恶的双重转换(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<Redux.Store.Definition> = createStore(rootReducer, middleware);
// Here the dispatch casting:
(store.dispatch as ThunkDispatch<Redux.Store.Definition, void, AnyAction>)( bootstrap() );
return store;
}
如果其他人正在寻找更新的答案!^^
发布于 2019-07-18 12:34:51
自从这个问题出现以来,时间已经过去了,许多事情也发生了变化,各种各样的答案也被张贴了出来。然而,我发现没有一个答案对我来说是令人满意的,因为前两个(michael和pierpytom)涉及重新定义/重新定义哪个感觉很奇怪。第三个(joaoguerravieira)似乎更好,因为它没有涉及其中任何一个,但不清楚,至少对我来说,它是如何解决问题的。
当我遇到一个我认为与此几乎相同的问题时,这对我来说似乎是最有帮助的:如何在创建的redux存储上获得一个正确类型的“分派”方法。也就是说,如何让TypeScript编译器同意store.dispatch可以分派操作或ThunkActions。即使这不是最初问题中所问到的问题(但我认为可能是这样),所有关于我问题的搜索引擎查询都让我回到了这个帖子,所以我认为把我的解决方案放在这里也许会有帮助。
在使用redux时,我总是发现找到合适的类型非常困难(也许我只是个傻瓜),所以很长一段时间以来,我总是像这样创建我的商店:
createStore(
combineReducers(stuff),
defaultState,
applyMiddleware(thunkMiddleware));
...which总是让我处于可以在块上调用store.dispatch的情况,但是TypeScript编译器对我大喊大叫,尽管它在运行时仍然可以工作。每一个答案的一些部分最终让我找到了我认为是解决这个问题的最先进、最不重要的方法。
在存储对象上键入调度方法取决于对redux的createStore的调用返回的内容。为了在存储的分派方法上具有正确的类型,您必须在调用applyMiddleware时正确地设置类型参数(您可以直接或最终将其作为第三个参数传递给createStore)。@joaoguerravieira的回答使我朝这个方向看。为了使调度方法具有正确的类型来分派ThunkAction或Action,我不得不调用createStore/apply中间件,如下所示:
createStore(
combineReducers(stuff),
defaultState,
applyMiddleware<DispatchFunctionType, StateType>(thunkMiddleware));
哪里
type DispatchFunctionType = ThunkDispatch<StateType, undefined, AnyAction>
通过这样做,我得到了一家这样的商店:
Store<StateType, Action<StateType>> & { dispatch: DispatchFunctionType };
...which为我提供了这种类型的store.dispatch函数:
Dispatch<Action<any>> & ThunkDispatch<any, undefined, AnyAction>
...which可以成功地分派一个操作或一个ThunkAction,而无需对类型大喊大叫,也不需要任何重新定义/转换。
正确设置对applyMiddleware的调用中的类型参数至关重要!
https://stackoverflow.com/questions/43013204
复制