Search code examples
angularngrxngrx-effects

Get the type from a - "createAction" function


There are two ways of creating an ngrx Action. One is to define a new class that implements the Action class and the other is to use the "createAction" function. Is there a way to get to the typings of an action that was created using the "createAction" method?

For example if I have this action:

export const getWorker = createAction(
  '[Worker Api] Get Worker',
  props<{ workerId: number }>()
);

I would like to get the workerId in an effect that listens to that action:

getWorker$ = createEffect(() => {
return this.actions$.pipe(
  ofType(WeatherApiActions.getWorker),
  switchMap((action: { type: string, workerId: number }) => this.workerService.getWorker(action.workerId)),
  map((worker: IWorker) => WeatherApiActions.getWorkerSuccess({ worker }))
)})

As you so I had to write the type myself. This makes the effect tightly coupled to the action and this is a huge drawback. So my question is: Do I must use the first way of creating an action in order to have the action payload typings?


Solution

  • I exactly needed it when I wanted to share some code inside my effect and figured it out.

    Answer to your question is, No. You can get Action type with a simple code.

    Using ReturnType utility type, you can extract Action type from the function created by createAction.

    Having the action created as below,

    const getWorker = createAction(
      '[Worker Api] Get Worker',
      props<{ workerId: number }>()
    );
    

    ReturnType<typeof getWorker> results in type { workerId: number } & TypedAction<'[Worker Api] Get Worker'>.

    If you look at the declaration code of ofType operator function in the library, you'll see it also uses ReturnType utility.