Набрав редуктор с библиотекой redux-actions - PullRequest
0 голосов
/ 29 мая 2018

Я пытаюсь набрать второй аргумент, action, моего редуктора сейчас, когда я использую createAction из библиотеки redux-actions.

Часть моего кода редуктора выглядит следующим образом

type AddItems = 'addItems';
const AddItems: AddItems = 'addItems';

interface AddItemAction extends Action<CartItem> {
    type: AddItems;
}

export const addItems = createAction<CartItem>(AddItems);

type RemoveItem = 'removeItem';
const RemoveItem: RemoveItem = 'removeItem';

interface RemoveItemAction extends Action<number> {
    type: RemoveItem;
}

export const removeItem = createAction<number>(RemoveItem);

export type ShoppingCartActions = AddItemAction | RemoveItemAction;

export const shoppingCartActions = {
    addItems,
    removeItem
};

export default function shoppingCartReducer(state: ShoppingCartStore = shoppingCartInitialState, action: ShoppingCartActions) {
    const { type, payload } = action;    
    switch (type) {
        case AddItems:
           return {
            cartItems: [
                ...state.cartItems.filter(cartItem => cartItem.item.id !== payload!.item.id),
                payload
            ]               
           };
        case RemoveItem:
           return {
               cartItems: [
                   ...state.cartItems.filter(cartItem => cartItem.item.id !== payload)
               ]
           };
        default:
            return state;
    }
}

Проблема, с которой я столкнулся, заключается в том, что, когда я получаю доступ к свойству payload в моем редукторе, он думает, что это свойство должно существовать для каждого случая.Например, в случае addItems я обращаюсь к payload.item, но машинопись выдает жалобу, потому что она также ищет, что item находится на номере типа, поступающем от RemoveItemAction.

1 Ответ

0 голосов
/ 29 мая 2018

Отказ от ответственности: у меня нет локально установленных библиотек redux или redux-actions, поэтому я не могу быть уверен на 100%, верен ли этот ответ;пожалуйста, проверьте его.


ShoppingCartActions - это дискриминируемый союз , где type - свойство дискриминанта.Вы ожидаете, что TypeScript будет действовать так, как объявлено при проверке дискриминанта: он должен автоматически сузить тип переменной action до соответствующей составляющей объединения.

К сожалению, вы разбиваете action на двапеременные type и payload, например:

const { type, payload } = action;    

, и компилятор не понимает, что типы type и payload коррелированы. если вы сузите type от AddItems | RemoveItem до AddItems, компилятор не автоматически сузит payload от CartItem | number до CartItem.Хотя мы знаем, что это должно быть так, компилятор не такой умный, как мы, и эвристика , которую он использует для анализа потока управления, не является задачей понимания"запутанные переменные", как это.

Вы не первый человек до бегите в этот вопрос .Комментарии разработчиков языка к этим вопросам обычно выглядят примерно так: «Было бы хорошо, если бы компилятор мог сделать это за вас, но это было бы очень дорого для реализации и привело бы к низкой производительности компилятора».


Самым простым решением в этом случае является использование различающихся союзов так, как намеревается TypeScript: не деструктурировать action.Вместо этого используйте прямой доступ к свойству action:

export default function shoppingCartReducer(
  state: ShoppingCartStore = shoppingCartInitialState, 
  action: ShoppingCartActions
) {
  // switch on property of action
  switch (action.type) {
    case AddItems:
      return {
        // action.payload is now CartItem
        cartItems: [              
          ...state.cartItems.filter(
            cartItem => cartItem.item.id !== action.payload!.item.id
          ),
          action.payload
        ]
      };
    case RemoveItem:
      // action.payload is now number
      return {
        cartItems: [
          ...state.cartItems.filter(
            cartItem => cartItem.item.id !== action.payload
          )
        ]
      };
    default:
      return state;
  }
}

Теперь это должно работать, как и предполагалось.


Надеюсь, это поможет.Удачи!

...