Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript, Unit Tests: Correct typing for Dispatching a Thunk with store.dispatch from redux-mock-store

Is there any way to correctly dispatch a Thunk from a store created with redux-mock-store ? Right now I am forced to use any type assertion

store.dispatch<any>(getCommissions());

As dispatch expects to provide plain Action

[ts]
Argument of type '(dispatch: ThunkDispatch<IRootState, undefined, 
AnyAction>, getState: () => IRootState) => void' is not assignable to parameter of type 'AnyAction'.
Property 'type' is missing in type '(dispatch: ThunkDispatch<IRootState, undefined, AnyAction>, getState: () => IRootState) => void'.

Code fragment for getCommisions()

export function getCommissions() {
  return (dispatch: ThunkDispatch<IRootState, undefined, AnyAction>, getState: () => IRootState) => { ... }
like image 870
adyry Avatar asked Oct 04 '18 13:10

adyry


2 Answers

The createMockStore function that is the default export of redux-mock-store accepts generic types <S, DispatchExts> where S is the definition of your Redux state, and DispatchExtsis a union of (or single) additional Dispatch signatures for any added Redux middleware.

So the way to set this up is to import ThunkDispatch from redux-thunk, which accepts its own generic arguments of <State, ExtraArgument, Action> and pass that in as the DispatchExts argument to createMockStore.

Here's an abbreviated example:

import { AnyAction } from 'redux'; // Or your own Action definition
import createMockStore from 'redux-mock-store';
import thunk, { ThunkDispatch } from 'redux-thunk';

import { ApplicationState } from '../your/definitions';

type DispatchExts = ThunkDispatch<ApplicationState, void, AnyAction>;

const middleware = [thunk];
const mockStore = createMockStore<ApplicationState, DispatchExts>(middleware);

const store = mockStore();

Hope that helps you!

My current versions: redux 4.0.0 redux-thunk 2.3.0 redux-mock-store 1.5.3 typescript 2.9.2

ThunkDispatch defintion https://github.com/reduxjs/redux-thunk/blob/master/index.d.ts

createMockStore definition https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/redux-mock-store/index.d.ts

like image 81
nickpassarella Avatar answered Oct 06 '22 04:10

nickpassarella


For configureMockStore use, the solution is almost exactly the same as the answer by @nickpassarella.

import configureMockStore from 'redux-mock-store';
import thunk, { ThunkDispatch } from 'redux-thunk';
import { MyState, MyActions } from './my-types';

type DispatchExts = ThunkDispatch<MyState, undefined, MyActions>;

const middlewares = [thunk];
const mockStore = configureMockStore<MyState, DispatchExts>(middlewares);

const store = mockStore();

Both examples working with redux 4.0.1 redux-thunk 2.3.0 redux-mock-store 1.5.3 and typescript 3.5.3

like image 44
Jade Montagu Avatar answered Oct 06 '22 04:10

Jade Montagu