router-store icon indicating copy to clipboard operation
router-store copied to clipboard

How to use with tagged union types?

Open mattdistefano opened this issue 8 years ago • 3 comments

Assume we have a reducer using tagged union types - i.e. function reducer(state: AppState, action: ActionTypeA | ActionTypeB | ActionTypeC): AppState { return state; } - and wanted to handle a router action. This doesn't seem to work out of the box since the actions are untyped.

mattdistefano avatar Jan 25 '17 19:01 mattdistefano

This should still work in your reducer. The type is still a string.

  switch (action.type) {
    case foo.ActionTypes.BAR:
      return Object.assign({}, state, { foo: bar });

    case routerActions.UPDATE_LOCATION:
      return state;

    default:
      return state;
  }

brandonroberts avatar Feb 02 '17 22:02 brandonroberts

The problem with that usage is that it seems to break the type inference magic typescript does w/ the union types and consequently I lose type checking on the action payload.

mattdistefano avatar Feb 02 '17 23:02 mattdistefano

I see. I'll looking to adding typed actions soon. You can also create your own typed action and use it in the reducer.

import { Action } from '@ngrx/store';
import { type } from '../utils/type';
import { routerActions, RouterMethodCall } from '@ngrx/router-store';

export const ActionTypes = {
  FOO: type('[Category] Foo'),
  UPDATE_LOCATION: type(routerActions.UPDATE_LOCATION)
};

export class ActionTypeA implements Action {
  type = ActionTypes.FOO;

  constructor(public payload?: boolean) {}
}

export class UpdateLocationAction implements Action {
  type = ActionTypes.UPDATE_LOCATION;

  constructor(public payload: { path: string }) {}
}

export type Actions = ActionTypeA | UpdateLocationAction;

brandonroberts avatar Feb 02 '17 23:02 brandonroberts