Как отправить действие или ThunkAction (в TypeScript, с redux-thunk)?
скажем, у меня есть такой код:
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
}
...Я получаю эту ошибку от компилятора 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
использовать.
есть ли способ обойти это?
3 ответов
Я думаю, вы правы в том, что, несмотря на возможность обрабатывать оба типа, typescript не может решить, какую перегрузку использовать.
Я думаю, что лучший вариант для вас-вернуться к нужному типу при вызове 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);
}
}
Я надеюсь, что я ошибаюсь, и есть лучший способ достичь этого.
подпись ThunkAction изменена с последней версией (теперь это ThunkAction<void, Your.Store.Definition, void, AnyAction>
) и если только какой-то злой двойной кастинг (action as {} as Action
), более элегантный способ, который я нашел, - определить Redux dispatch как 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;
}
В случае, если кто-то еще ищет обновленные ответ! ^^
это правильные типизации:https://github.com/reduxjs/redux-thunk/blob/master/test/typescript.ts
в частности:
const store = createStore(fakeReducer, applyMiddleware(thunk as ThunkMiddleware<State, Actions>));
applyMiddleware
уже переопределит отправку с помощью ThunkDispatch
.