Disons que j'ai le code comme suit:
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
}
... Je reçois cette erreur du compilateur 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>'.
Je pense que le problème tient à la manière dont le fichier de définition de type redux-thunk
augmente l'interface redux
Dispatch
et à l'incapacité de TypeScript de savoir quelle définition de Dispatch
utiliser.
Y a-t-il un moyen de contourner ceci?
Je pense que vous avez raison, même si vous êtes capable de gérer les deux types, TypeScript ne peut pas déterminer quelle surcharge utiliser.
Je pense que la meilleure option pour vous est de rétablir le type souhaité lorsque vous appelez 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);
}
}
J'espère que je me trompe et qu'il existe un meilleur moyen d'y parvenir.
La signature de ThunkAction a changé avec la dernière version (c'est maintenant ThunkAction<void, Your.Store.Definition, void, AnyAction>
) et à moins qu'un double casting maléfique (action as {} as Action
), la façon la plus élégante que j'ai trouvée est de définir l'envoi de redux comme un ThunkDispatch comme ceci:
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;
}
Si quelqu'un d'autre cherche une réponse à jour! ^^
Ce sont les typages corrects: https://github.com/reduxjs/redux-thunk/blob/master/test/TypeScript.ts
Notamment:
const store = createStore(fakeReducer, applyMiddleware(thunk as ThunkMiddleware<State, Actions>));
applyMiddleware
annulera déjà l'envoi avec un ThunkDispatch
.