Отказ от ответственности: у меня нет локально установленных библиотек 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;
}
}
Теперь это должно работать, как и предполагалось.
Надеюсь, это поможет.Удачи!