Home > Software engineering >  What is the typescript equivalent for Asynchronous action in Redux-toolkit
What is the typescript equivalent for Asynchronous action in Redux-toolkit

Time:05-19

I am trying to add typescript to redux toolkit app. This is a simple counter app, to increase or decrease the counter state by one.

import {
  createSlice,
  Dispatch,
  PayloadAction
} from "@reduxjs/toolkit";

export interface CounterState {
  value: number;
};

const initialState: CounterState = {
  value: 0
};

export const counterSlice = createSlice({
  name: 'Counter Slice',
  initialState: initialState,
  reducers: {
    increment: (state) => {
      state.value = state.value   1;
    },
    decrement: (state) => {
      state.value = state.value - 1;
    },
    incrementByAmount: (state, action: PayloadAction < number > ) => {
      state.value = state.value   action.payload;
    }
  }
});

//What would be the type of "incrementAsync"
export const incrementAsync: any = (amount: number) => (dispatch: Dispatch) => {
  setTimeout(() => {
    dispatch(incrementByAmount(amount));
  }, 1000);
};

export const {
  increment,
  decrement,
  incrementByAmount
} = counterSlice.actions;
export default counterSlice.reducer;

What should be the type annotation for incrementAsync instead of the any type I have used just to make it work. The official redux toolkit documentation didn't help me.

The incrementAsync is just using a timeout function to increase the counter value by one after a delay of one second.

CodePudding user response:

I think you need to use createAsyncThunk(). Together with TypeScript this can look like this:

export const incrementAsync = createAsyncThunk<void, number>(
  "counter/incrementAsync",
  async (amount, { dispatch }) => {
    setTimeout(() => {
      dispatch(incrementByAmount(amount))
    }, 1000)
  }
)

That way your function incrementAsync is typed via inferring the type from the function createAsyncThunk()

Reference for createAsyncThunk together with TypeScript

CodePudding user response:

You don't need a type annotation there - TypeScript already knows very well that

(amount: number) => (dispatch: Dispatch) => {
  setTimeout(() => {
    dispatch(incrementByAmount(amount));
  }, 1000);
};

is of the type

(amount: number) => (dispatch: Dispatch) => void

.

You don't need to write that down and don't need an alias for that - it will work nicely with Redux already. Just skip the manual type annotation on your const.

You can use an AppThunk type as described in Type Checking Redux Thunks, but there is not a lot of benefit to it and tbh., I find it more difficult to handle.

Or you go, as already suggested in the other answer, with createAsyncThunk, but you only should do that if you have something that really needs a lifecicle, so a "pending" action before and a "fulfilled" or "rejected" action afterwards.

  • Related