【问题标题】:How to properly use PayloadAction with meta type in redux-toolkit?如何在 redux-toolkit 中正确使用带有元类型的 PayloadAction?
【发布时间】:2020-06-04 19:43:35
【问题描述】:

简化示例

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

    type Cake = {
      flavor: string;
      size: 'S' | 'M' | 'L';
    };

const initialState: { all: Cake[]; meta: { currentPage: number } } = {
  all: [],
  meta: {
    currentPage: 0,
  },
};

const cakeSlice = createSlice({
  name: 'cake',
  initialState,
  reducers: {
    fetchAll(
      state,
      action: PayloadAction<Cake[], string, { currentPage: number }>,
    ) {
      state.all = action.payload;
      state.meta = action.meta;
    },
  },
});

export default cakeSlice;

我收到这些错误。

Type '
(state: {
    all: {
        flavor: string;size: "S" | "M" | "L";
    } [];meta: {
        currentPage: number;
    };
}, action: PayloadAction < Cake[], string, {
    currentPage: number;
}, never > ) => void ' is not assignable to type '
CaseReducer < {
    all: Cake[];meta: {
        currentPage: number;
    };
}, {
    payload: any;type: string;
} > | CaseReducerWithPrepare < {
    all: Cake[];meta: {
        currentPage: number;
    };
}, {
    payload: any;type: string;
} > '
Type '
(state: {
    all: {
        flavor: string;size: "S" | "M" | "L";
    } [];meta: {
        currentPage: number;
    };
}, action: PayloadAction < Cake[], string, {
    currentPage: number;
}, never > ) => void '
is not assignable to type 'CaseReducer<{ all: Cake[]; meta: { currentPage: number; }; }, { payload: any; type: string; }>'.
Types of parameters 'action'
and 'action'
are incompatible.
Type '{ payload: any; type: string; }'
is not assignable to type 'PayloadAction<Cake[], string, { currentPage: number; }, never>'.
Property 'meta'
is missing in type '{ payload: any; type: string; }'
but required in type '{ meta: { currentPage: number; }; }
'.

【问题讨论】:

  • 你最终解决了这个问题吗?是否有用于解决问题的 RTK 更新?
  • 我认为最新版本已经解决了这个问题@ksav

标签: reactjs typescript redux react-redux redux-toolkit


【解决方案1】:

RTK 的默认行为是创建一个只有一个参数和一个有效负载属性的动作创建者。 TS 注释无法修改此行为,因为 TS 注释对运行时行为没有影响。

您可以使用the prepare notation 定义一个覆盖此默认行为的函数。 此函数与prepare argument for createAction 具有相同的签名和行为,因此您可以在那里找到大部分相关文档。

在你的具体情况下,你会想要一些类似于

的东西
const cakeSlice = createSlice({
  name: 'cake',
  initialState,
  reducers: {
    fetchAll: {
      reducer(
        state,
        action: PayloadAction<Cake[], string, { currentPage: number }>
      ) {
        state.all = action.payload
        state.meta = action.meta
      },
      prepare(payload: Cake[], currentPage: number) {
        return { payload, meta: { currentPage } }
      }
    }
  }
})

这里是typescript playground

【讨论】:

  • 谢谢。我听从了你的建议,但不幸的是,我仍然遇到同样的问题。 ` 类型'{ 有效负载:任何; 中缺少属性'meta';类型:字符串; }' 但在类型 '{ meta: { currentPage: number; }; }' `
  • 在此代码框中运行良好:codesandbox.io/s/frosty-platform-w274k 以及 TS 操场(将其编辑为答案)您使用的是哪个版本的 TS?
  • 我正在使用 typescript 3.7.5 先生
  • 很奇怪。我的意思是,它绝对可以在操场和代码盒中看到。任何不寻常的tsconfig 设置?像 strictNullChecks disabled 之类的东西或类似的东西?
  • 感谢您的宝贵时间。这是我的 tsconfig.json github.com/reduxjs/redux-toolkit/issues/…
猜你喜欢
  • 2022-01-22
  • 1970-01-01
  • 2021-07-11
  • 2021-05-24
  • 1970-01-01
  • 2021-11-06
  • 1970-01-01
  • 2021-07-19
  • 2019-11-19
相关资源
最近更新 更多