简体   繁体   中英

How to fix typescript error in redux-toolkit?

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;

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> ) 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:

  1. You can increment the value directly using the addition assignment operator +=
const increment: CaseReducer<State,PayloadAction<number>> = (state, action) => {
  state.value += action.payload;
}
  1. You can assign a new value to the state.value property with assignment operator =
const increment: CaseReducer<State,PayloadAction<number>> = (state, action) => {
  state.value = state.value + action.payload;
}
  1. (Not recommended) You can return an entirely new state. I am using parentheses around curly braces to return an object with the property 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.

CaseReducer return value must be void | State | WritableDraft void | State | WritableDraft 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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM