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.