【问题标题】:How to fix typescript error in redux-toolkit?如何修复 redux-toolkit 中的 typescript 错误?
【发布时间】:2021-04-10 07:23:56
【问题描述】:

我正在用 typescript 做一个 redux-toolkit 教程。但我是打字稿初学者。

我不知道这里有什么问题。请给我你的见解。

这是一条错误消息。 : TS2322: 类型 'number' 不能分配给类型 'void |状态 |可写草稿'。

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;

【问题讨论】:

    标签: typescript redux redux-toolkit


    【解决方案1】:

    没有大括号的箭头函数是implied return。所以你返回state.value + action.payload,这是一个number

    Redux Toolkit 允许您返回新状态(在回答此问题时输入 State | WritableDraft&lt;State&gt;,或在较新版本的 RTK 中输入 State | Draft&lt;State&gt;)或修改草稿状态而不返回任何内容(输入 void )。您会收到 Typescript 错误,因为返回 number 既不是也不是这些。

    您可能想要修改草稿状态,因此您需要在函数体周围加上花括号,这样您就不会返回任何内容。


    这三个函数都是有效的。从最详细到最详细排序:

    1. 您可以使用addition assignment operator += 直接增加值
    const increment: CaseReducer<State,PayloadAction<number>> = (state, action) => {
      state.value += action.payload;
    }
    
    1. 您可以使用assignment operator =state.value 属性分配一个新值
    const increment: CaseReducer<State,PayloadAction<number>> = (state, action) => {
      state.value = state.value + action.payload;
    }
    
    1. (不推荐)您可以返回一个全新的状态。我在 return an object 的大括号周围使用括号,属性为 value
    const increment: CaseReducer<State,PayloadAction<number>> = (state, action) => ({
      value: state.value + action.payload
    });
    

    如果有 value 以外的属性,您需要像 {...state, value: newValue } 一样复制它们,这就是您在传统 Redux reducer 中看到的。 Redux Toolkit 使选项 1 和 2 可用,因此您不必这样做。但是如果你选择返回一个新的状态,那么它必须是一个完整的状态。

    【讨论】:

    • 感谢您的详细解释!!这个问题是我对 JavaScript 和 Redux 缺乏了解。
    • @Linda Paiste 我可以知道可写草稿是什么。所以我确实试图找到那是什么,但在任何地方都找不到?
    • @kevinTHEprogrammer WritableDraft 类型来自 immer,这是 Redux Toolkit 在后台用于不可变更新的包。 WritableDraft 曾经被 Redux Toolkit 重新导出,但现在他们似乎改用了 immer Draft 类型。
    【解决方案2】:

    CaseReducer 返回值必须是void | State | WritableDraft 而你的表达式:

    (state, action) => state.value + action.payload
    

    是一个返回数字的函数。解决方法是在返回值前加上void运算符,设置为undefined

    (state, action) => void (state.value += action.payload)
    

    【讨论】:

    • 那还是要注意的。设为(state, action) =&gt; { state.value += action.payload }(state, action) =&gt; { state.value = state.value + action.payload }
    • @phry 我不确定你的意思,但它适用于this 代码框。这里还有typescript playground
    • 它不再有类型错误,但它在运行时也不做任何事情,因为它将两个数字相加并丢弃结果。提问者的意图是将两个数字相加并重新分配给state.value
    • @phry 哦,我终于明白你的意思了。谢谢你纠正我。我更关注修复类型错误而不是逻辑本身。
    猜你喜欢
    • 1970-01-01
    • 2021-08-23
    • 2021-04-19
    • 1970-01-01
    • 1970-01-01
    • 2021-07-06
    • 2013-06-17
    • 2022-01-22
    • 2021-11-18
    相关资源
    最近更新 更多