4 comments

[ 2.9 ms ] story [ 16.1 ms ] thread
I'll have to try this. I was really interested in using TypeScript with Redux, but gave up because I couldn't figure out a good way to type actions.
Tagged unions are indeed pretty helpful for Redux reducers. One thing to note is that you can actually skip some code here as well. Specifically, the constant definitions:

  export type INCREMENT_COUNTER = 'App/INCREMENT_COUNTER';
  export const INCREMENT_COUNTER : INCREMENT_COUNTER = 'App/INCREMENT_COUNTER';
These aren't necessary, you can use those type strings directly:

  export interface IncrementCounterAction = {
      type: 'App/INCREMENT_COUNTER',
      by: number
  };
In vanilla, untyped Redux the constants are a good idea because they give you some safety and IDE-ability. With Typescript they're just a waste of code, since TS is going to check those type strings for you. Cut out the middleman!
Could you then do the case statements in the reducer like this?

    switch (action.type) {
    case IncrementCounterAction.type:
        return state.update(...);
    case DeccrementCounterAction.type:
        return state.update(...);
    ....
    }
I believe you can, though I haven't tried it. Typescript will actually give you completion support for plain strings inside that switch statement, which is normally what I go with.