我正在努力输入我的reducer的第二个参数,action,因为我使用createAction
库中的redux-actions
。
我的reducer代码的一部分如下
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;
}
}
我遇到的问题是当我在reducer中访问payload
上的属性时,它认为每个案例都必须存在该属性。例如,在addItems
的情况下,我访问了payload.item
,但是却因为它item
寻找RemoveItemAction
来自client.on('messageReactionAdd', (reaction, user) => {
reaction.message.channel.send(`${user} reacted to ${reaction.message.author} with ${reaction._emoji.name}`);
});
的<{1}}。
答案 0 :(得分:1)
免责声明:我没有在本地安装redux或redux-actions库,因此如果答案是正确的,我无法100%确定;请测试一下。
ShoppingCartActions
是discriminated union,其中type
是判别属性。当你检查判别式时,你期望TypeScript充当广告:它应该自动将action
变量的类型缩小到联合的适当组成部分。
很遗憾,您正在将action
解构为两个变量type
和payload
,如下所示:
const { type, payload } = action;
并且编译器不理解type
和payload
的类型是相关的。也就是说,如果从{{1}缩小type
} AddItems | RemoveItem
,编译器不自动将AddItems
从payload
缩小到CartItem | number
。即使我们知道必须如此,编译器也不如我们聪明,并且它用来分析控制流的heuristics不能理解& #34;纠缠变量&#34;像这样。
not first人to into issue JAR。语言设计者在这些问题上的评论通常类似于#34;如果编译器可以为你做这件事会很好,但实现它会非常昂贵并导致编译器性能不佳&#34;。
在这种情况下最简单的解决方法是按照TypeScript的方式使用有区别的联合:不要解构CartItem
。请改为使用action
上的直接属性访问:
action
我认为这应该按预期运作。
希望有所帮助。祝你好运!