Skip to content

Typescript & Middleware extensions #1712

Closed
@pfgray

Description

@pfgray

Hi,

I'm wondering how the typescript type definitions for extension via middleware are supposed to work (when extending the types of Actions that are possible).

For instance, let's take the module redux-thunk (one of the simplest redux middlewares).

It allows you to dispatch a function with type: (Dispatch, ()=>S) => void, (that is, a function whose first parameter is the dispatch function, and whose second parameter is the getState function).

suppose I have a trivial type definition for redux-thunk:

declare module "redux-thunk" {
  import { Middleware } from 'redux';
  const thunkMiddleware: Middleware;
  export default thunkMiddleware;
}

And I use it in my app to create a store like:

import { Reducer, createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';

const myReducer: Reducer<number> = (count, action) => count;

const myStore = createStore(myReducer, applyMiddleware(thunk));

I can't dispatch a redux-thunk function:

// fails with: Argument of type '(dispatch: any) => number' is not assignable to parameter of type 'Action'.
myStore.dispatch(dispatch =>
  setTimeout(() =>
    dispatch({
      type: "INCREMENT_COUNT"
    })
  , 500)
)

This is a complex api to account for in a type system, since the signature of dispatch changes depending on what middleware is loaded:

<A extends Action> dispatch(action: A)

becomes:

dispatch(action: Action | ThunkAction)

(where ThunkAction is (Dispatch, ()=>S) => void from above.

I'm not really sure immediately how to address this, but I was just wondering if there is an intended way to work with redux middleware.

cc'ing @aikoven @Igorbek @use-strict

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions