2

如果我生成这样的动作:

export const updateParticularObjectValue = createAction(
    UPDATE_PARTICULAR_VALUE,
    (id: string, amount: number, reason: string = 'default') => { 
        return { id, value: amount, reason }; 
    },
);

出于某种原因,我的 IDE(实际上是我的打字稿编译器)抱怨说,当我显式传递第三个参数时,调用动作创建者只需要两个参数。我希望创建者可以选择使用第三个参数...有没有办法使用 redux-actionscreateAction函数来做到这一点,还是我需要手动构建动作创建者?

PS - 这种语法也会导致相同的结果:

export const updateParticularObjectValue = createAction(
    UPDATE_PARTICULAR_VALUE,
    (id: string, amount: number, reason?: string) => { 
        return { id, value: amount, reason: reason || 'default' }; 
    },
);

似乎以任何方式使第三个参数成为可选参数不会在打字稿中翻译——它被视为不存在,并且对函数的调用禁止包含它。有没有解决的办法?

PPS - 如果您可以“欺骗”打字稿编译器(在我的情况下,通过在反应组件中使用“连接”时在组件的 Props 类型中定义函数接口)它工作正常,它只是没有通过编译器的气味测试当明确调用它时 - 似乎没有真正的理由应该发生这种情况。

PPPS——在这一点上,我找到了一个可行的解决方案。但是,我仍然对为什么这是 createAction 的打字稿实现的限制以及是否有任何替代解决方案可以更好/更智能地解决这种情况感兴趣。一个好的解释对我自己和可能的其他人都有教育意义。

4

2 回答 2

2

您可以使用箭头函数返回createAction函数执行以下操作:

interface ActionProps {
    id: string;
    amount: number;
    reason: string;
}

export const updateParticularObjectValue = (props: ActionProps) => (createAction('UPDATE_PARTICULAR_VALUE', {
    id: props.id,
    value: props.amount,
    reason: props.reason
}));
于 2018-03-25T23:53:43.360 回答
0

因此,根据@FisNaN 的原始响应,似乎最干净的解决方案是将动作创建者包装在一个容器函数中,并允许动作创建者本身考虑所有强制输入,例如:

// allow a default
export const updateObjectValue = (id: string, amount: number, reason: string = 'default') => {
    return updateObjectValueWithReason(id, amount, reason);
}
// do it for real
const updateObjectValueWithReason = createAction(
    UPDATE_PARTICULAR_VALUE,
    (id: string, amount: number, reason: string) => { 
        return { id, value: amount, reason }; 
    },
);

如果你真的需要你的 reducer 来确定默认值,你总是可以创建两个 action creators 并让你的包装器选择要触发的:

// allow a default
export const updateObjectValue = (id: string, amount: number, reason?: string) => {
    return typeof reason === 'undefined'
        ? updateObjectValueWithoutReason(id, amount)
        : updateObjectValueWithReason(id, amount, reason);
}
// take a reason and send it through the action
const updateObjectValueWithReason = createAction(
    UPDATE_PARTICULAR_VALUE,
    (id: string, amount: number, reason: string) => { 
        return { id, value: amount, reason }; 
    },
);
// send no reason through the action, let reducer decide
const updateObjectValueWithoutReason = createAction(
    UPDATE_PARTICULAR_VALUE,
    (id: string, amount: number) => { 
        return { id, value: amount }; 
    },
);

我仍然不是 100% 清楚为什么 createAction 函数返回的打字稿 typedef 完全省略了可选参数,但是这种方法应该允许您在 actionCreators 中使用可选参数。

于 2018-03-26T18:10:42.277 回答