Reputation: 131
I'm doing a redux-toolkit tutorial with typescript. But I'm a typescript beginner.
I don't know what the problem is here. Please give me your insight.
This is an error message. : TS2322: Type 'number' is not assignable to type 'void | State | WritableDraft'.
import {CaseReducer, createSlice, PayloadAction} from "@reduxjs/toolkit";
type State = {
value: number
}
const increment: CaseReducer<State,PayloadAction<number>> = (state, action) => state.value + action.payload; // error line
export const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0
},
reducers: {
increment,
decrement: state => {
state.value -= 1
},
incrementByAmount: (state, action) => {
state.value += action.payload
},
},
})
export const {increment, decrement, incrementByAmount} = counterSlice.actions;
export default counterSlice.reducer;
Upvotes: 10
Views: 26113
Reputation: 88
I resolved this by updating my typescript version to recommended version
Upvotes: 0
Reputation: 42188
An arrow function without curly braces around it is an implied return. So you are returning state.value + action.payload
which is a number
.
Redux Toolkit allows you to either return a new state (type State | WritableDraft<State>
at the time of this answer, or type State | Draft<State>
in newer versions of RTK) or modify the draft state and not return anything (type void
). You get a Typescript error because returning number
is neither or these.
You likely want to modify the draft state, so you need curly braces around your function body so that you aren't returning anything.
These three functions are all valid. Ordered from least to most verbose:
+=
const increment: CaseReducer<State,PayloadAction<number>> = (state, action) => {
state.value += action.payload;
}
state.value
property with assignment operator =
const increment: CaseReducer<State,PayloadAction<number>> = (state, action) => {
state.value = state.value + action.payload;
}
value
.const increment: CaseReducer<State,PayloadAction<number>> = (state, action) => ({
value: state.value + action.payload
});
If there were properties other than value
you would need to copy them like {...state, value: newValue }
which is what you see in traditional Redux reducers. Redux Toolkit makes options 1 and 2 available so that you don't have to do this. But if you chose to return a new state then it must be a complete state.
Upvotes: 10
Reputation: 81370
CaseReducer
return value must be void | State | WritableDraft
while your expression:
(state, action) => state.value + action.payload
Is a function that returns a number. The solution is to add the void
operator before the return value to set it to undefined
.
(state, action) => void (state.value += action.payload)
Upvotes: 0