Search code examples
typescriptngrx

How to use Generic Type in NgRx createAction props<>()


I want to create an NgRx action creator factory. But I don't know how it is possible to pass in a generic type to the props method.

import { createAction, props } from "@ngrx/store";

function actionFactory<T>(name: string) {
  return createAction(name, props<T>());
//                          ^^^^^^^^^^
}

It throws this error

Type 'Props<T>' provides no match for the signature '(...args: any[]): object'

How do I need to modify the factory method to pass a generic type into the props method like this?:

const action = actionFactory<{ id: string }>("sample");

You can try it yourself on Stackblitz


Solution

  • It seems @ngrx/store - from some reasons - prevents creating actions with empty objects. Here is a possible solution respecting @ngrx/store requirements and making actions fully typed:

    import { createAction, props, Props, NotAllowedCheck } from "@ngrx/store";
    
    // T extends object meets the condition of props function
    function actionFactory<T extends object>(name: string) {
      // restricting config type to match createAction requirements
      return createAction(name, props<T>() as Props<T> & NotAllowedCheck<T>);
    }
    
    // ok
    const action = actionFactory<{ id: string }>("sample");
    
    // empty object picked up on type level
    const emptyAction = actionFactory<{}>("sample");
    emptyAction({}); // error as expected properly
    

    STACKBLITZ