Search code examples
typescriptredux-toolkit

RTK - prepare payload (Typescipt)


My understanding is that a 'prepare' notation is needed for purposes of Typescript annotations. I'm struggling to convert this reducer to the 'prepare' annotation. Otherwise, TS throws the following error:

TS2339: Property 'meta' does not exist on type '{ payload: any; type: string; }'.

The code:

 getAllOrders: (state, action) => {
      state.orders = action.payload.orders;

      if (!!action.meta.status && action.meta.status === 'completed') {
        state.allLoaded = true;
      }
    },

How would I rewrite it using the 'prepare' format? Thank you.


Solution

  • The third argument of PayloadAction generic should contain type for .meta property.

    here's working demo on Github

    working code:

    // define custom meta
    interface CustomMeta {
      status: 'completed' | 'incomplete';
    }
    
    // define custom action with meta info
    type CustomAction = PayloadAction<number, string, CustomMeta>
    
    export const sampleSlice = createSlice({
      name: "sample",
      initialState,
      reducers: {
        // Use the PayloadAction type to declare the contents of `action.payload`
        getAllOrders: {
          reducer: (state, action: CustomAction) => {
            // the code below should not get any warnings
            if (action.meta?.status === "completed") {
              // ... do something
            }
          },
          // argument for prepare function has to be manually defined.
          prepare(payload: CustomAction['payload']) {
            return { payload, meta: { status: "completed" } } as CustomAction;
          },
        },
      },
    });
    

    check the type definition in createAction.d.ts for more info:

    for shortcut, Cmd+click or Ctrl+click on PayloadAction in VSCode

    export declare type PayloadAction<P = void, T extends string = string, M = never, E = never> = {
        payload: P;
        type: T;
    } & ([M] extends [never] ? {} : {
        meta: M;
    }) & ([E] extends [never] ? {} : {
        error: E;
    });