Ошибка ввода потока: Невозможно вызвать диспетчеризацию с литералом объекта, связанным с действием, потому что: - PullRequest
0 голосов
/ 03 февраля 2020

Я получаю следующую ошибку в потоке:

Невозможно вызвать диспетчеризацию с литералом объекта, связанным с действием, потому что:

• Любой строковый литерал REMOVE_FROM_CART [1] несовместим со строковым литералом ADD_TO_CART [ 2] в типе свойства.

• Или строковый литерал ADD_TO_CART [1] несовместим со строковым литералом REMOVE_FROM_CART [3] в типе свойства.

• Или строковый литерал ADD_TO_CART [1] несовместим с строковый литерал INCREMENT [4] в типе свойства.

• Или строковый литерал ADD_TO_CART [1] несовместим со строковым литералом DECREMENT [5] в типе свойства.

• Или строковый литерал ADD_TO_CART [1 ] несовместим со строковым литералом DISPLAY_PRODUCT_DETAIL [6] в типе свойства.

Я получаю ошибку в функции отправки, помеченной как ** dispatch ** ниже

export const updateCart = (id: number, type: ProductActionsType) => {
    return (dispatch: Dispatch<ProductActionsReturnTypes>) => {
       **dispatch({ type, payload: id });**
       dispatch({ type: UPDATE_TOTALS });
     };
 };

Файл: константы. js

export const FETCH_ITEMS = "FETCH_ITEMS";
export const ADD_TO_CART: "ADD_TO_CART" = "ADD_TO_CART";
export const REMOVE_FROM_CART: "REMOVE_FROM_CART" = "REMOVE_FROM_CART";
export const DISPLAY_PRODUCT_DETAIL: "DISPLAY_PRODUCT_DETAIL" =
  "DISPLAY_PRODUCT_DETAIL";
export const INCREMENT: "INCREMENT" = "INCREMENT";
export const DECREMENT: "DECREMENT" = "DECREMENT";
export const UPDATE_TOTALS: "UPDATE_TOTALS" = "UPDATE_TOTALS";
export const CLEAR_CART: "CLEAR_CART" = "CLEAR_CART";
export const OPEN_MODAL: "OPEN_MODAL" = "OPEN_MODAL";
export const CLOSE_MODAL: "CLOSE_MODAL" = "CLOSE_MODAL";

Файл: src / types / index. js

export type ClearCartActionType = {|
type: typeof CLEAR_CART
|};

type AddToCartActionType = {|
type: typeof ADD_TO_CART,
payload: number
|};

type RemoveFromCartActionType = {|
type: typeof REMOVE_FROM_CART,
payload: number
|};

export type DisplayProductDetailAction = {|
type: typeof DISPLAY_PRODUCT_DETAIL,
payload: number
|};

type IncrementActionType = {|
type: typeof INCREMENT,
payload: number
|};

type DecrementActionType = {|
type: typeof DECREMENT,
payload: number
|};

export type UpdateTotalsActionType = {|
type: typeof UPDATE_TOTALS
|};

export type ModalPayloadType = {|
id: number,
products: Array<ProductType>
|};

export type ProductActionsType =
| typeof ADD_TO_CART
| typeof REMOVE_FROM_CART
| typeof INCREMENT
| typeof DECREMENT
| typeof UPDATE_TOTALS
| typeof DISPLAY_PRODUCT_DETAIL
| typeof CLEAR_CART;

export type ProductActionsReturnTypes =
| AddToCartActionType
| RemoveFromCartActionType
| IncrementActionType
| DecrementActionType
| UpdateTotalsActionType
| DisplayProductDetailAction
| ClearCartActionType;

Я с укрой с этим. Кто-нибудь может предложить решение этой проблемы?

Ссылка потока для воспроизведения проблемы ссылка

1 Ответ

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

Это не правильный ответ, так как это альтернатива. Мне не удалось заставить ваш пример работать, и в целом мне было сложно работать с типами объектов и спредами в Flow, поэтому я решил эту проблему. Это упрощенный пример, включающий достаточно действий, чтобы показать используемый стиль.

type Dispatch<A, B> = A => B;

class AddToCartAction {
  payload: number;
  constructor(payload: number) {
    this.payload = payload;
  }
}

class RemoveFromCartAction {
  payload: number;
  constructor(payload: number) {
    this.payload = payload;
  }
}

class UpdateTotalsAction {}

/*
 * I removed the additional type annotations from the constants here,
 * and put their literal values in ProductActionsType instead. While
 * this adds some duplication, it works alongside Flow better. If the
 * annotations are used on the constants, and anyone forgets to add one
 * to a new constant, then ProductActionsType will have its type inferred
 * as "string", thus invisibly reducing type safety by allowing more
 * inputs than desired. By putting the literal strings in both the
 * constants and the types, the type system will catch you if you make
 * a typo, and it becomes more clear what is allowed as a
 * ProductActionsType.
 */
export const ADD_TO_CART = "ADD_TO_CART";
export const REMOVE_FROM_CART = "REMOVE_FROM_CART";
export const UPDATE_TOTALS = "UPDATE_TOTALS";

export type ProductActionsType =
| "ADD_TO_CART"
| "REMOVE_FROM_CART"
| "UPDATE_TOTALS";


export type ProductActionsReturnTypes =
| AddToCartAction
| RemoveFromCartAction
| UpdateTotalsAction;

export const updateCart = (id: number, type: ProductActionsType) => {
    return (dispatch: Dispatch<ProductActionsReturnTypes, void>) => {
        const action =
              type === "ADD_TO_CART"      ? new AddToCartAction(id)
        :     type === "REMOVE_FROM_CART" ? new RemoveFromCartAction(id)
        :     /* else UPDATE_TOTALS      */ new UpdateTotalsAction();
        dispatch(action);
        dispatch(new UpdateTotalsAction());
      };
 };

Основная идея c заключается в том, что вместо использования объектов с полем type один класс сделано для каждого типа. Уточнения типов потока очень и очень хороши при работе с классами, и легче понять сигнатуры типов и ошибки типов, когда несколько типов не объединяются в один.

Вложенные троичные выражения можно прочитать как альтернативу оператор switch / case, с дополнительным преимуществом, что они могут обрабатывать произвольные логические выражения в своем состоянии. Например, я бы обработал действия с кодом, подобным следующему:

function handleActions(a: ProductActionTypes) {
  return a instanceof AddToCartAction      ? handleAddToCart(a.payload)
  :      a instanceof RemoveFromCartAction ? handleRemoveFromCart(a.payload)
  :      /* a is an UpdateTotalsAction    */ handleUpdateTotals();
}

Этот синтаксис можно увидеть в разделе «Условные цепочки» Документы MDN для троичных выражений. Он хорошо работает с Flow, который будет знать тип a в каждой правой части условных выражений. Flow даже узнает, если вы забыли проверить случай, поскольку последнее условное условие предполагает, что все остальные классы типа ProductActionTypes уже проверены.

Надеюсь, это полезно, даже если это не так. т именно то, что вы искали. Я пишу весь свой код Flow в этом стиле, и с тех пор, как я начал это делать, у меня не было действительно грубых, запутанных ошибок типов.

...