使用redux-actions库键入reducer

时间:2018-05-29 01:46:14

标签: reactjs typescript redux redux-actions

我正在努力输入我的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}}。

1 个答案:

答案 0 :(得分:1)

免责声明:我没有在本地安装redux或redux-actions库,因此如果答案是正确的,我无法100%确定;请测试一下。

ShoppingCartActionsdiscriminated union,其中type是判别属性。当你检查判别式时,你期望TypeScript充当广告:它应该自动将action变量的类型缩小到联合的适当组成部分。

很遗憾,您正在将action解构为两个变量typepayload,如下所示:

const { type, payload } = action;    

并且编译器不理解typepayload的类型是相关的。也就是说,如果从{{1}缩小type } AddItems | RemoveItem,编译器自动将AddItemspayload缩小到CartItem | number。即使我们知道必须如此,编译器也不如我们聪明,并且它用来分析控制流的heuristics不能理解& #34;纠缠变量&#34;像这样。

not firstto into issue JAR。语言设计者在这些问题上的评论通常类似于#34;如果编译器可以为你做这件事会很好,但实现它会非常昂贵并导致编译器性能不佳&#34;。

在这种情况下最简单的解决方法是按照TypeScript的方式使用有区别的联合:不要解构CartItem 。请改为使用action上的直接属性访问:

action

我认为这应该按预期运作。

希望有所帮助。祝你好运!