Как правильно использовать PayloadAction с мета-типом в redux-toolkit? - PullRequest
0 голосов
/ 20 февраля 2020

Упрощенный пример

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; }; }
'.

1 Ответ

1 голос
/ 20 февраля 2020

Поведение RTK по умолчанию заключается в создании создателя действия только с одним аргументом и только свойством полезной нагрузки. Это поведение не может быть изменено аннотациями TS, поскольку аннотации TS не влияют на поведение во время выполнения.

Вы можете использовать нотацию prepare , чтобы определить функцию, которая переопределяет это поведение по умолчанию. Эта функция имеет ту же сигнатуру и поведение, что и аргумент prepare для createAction , поэтому вы можете найти там большую часть соответствующей документации.

В вашем конкретном случае c вы ' Я хочу что-то вроде

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

Вот это как машинописная площадка

...