redux-actions有效负载中的createAction默认参数(typeScript)

时间:2018-03-25 23:34:31

标签: typescript redux redux-actions

如果我生成这样的动作:

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

出于某种原因,我的IDE(实际上是我的打字稿编译器)抱怨说,当我明确地传递第三个参数时,调用动作创建者只需要两个参数。我希望创建者可选地使用第三个参数...有没有办法使用redux-actions createAction函数执行此操作,或者我是否需要手动构建动作创建者?

P.S。 - 此语法也会导致相同的结果:

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

似乎使得第三个参数以任何方式可选不会在typescript中转换 - 它被视为不存在并且调用该函数禁止包含它。有办法解决这个问题吗?

P.P.S。 - 如果你能傻瓜'打字稿编译器(在我的例子中,通过在反应组件中使用' connect'来定义组件的Props类型中的函数接口)它工作正常,它只是没有通过编译器和' #39;明确地调用它时的气味测试 - 似乎没有真正的原因会发生这种情况。

P.P.P.S。 - 此时,我找到了一个可行的解决方案。但是,我仍然对为什么这是createAction的打字稿实现的限制以及是否有任何替代解决方案对这种情况更好/更聪明感兴趣。一个好的解释对我自己和其他人来说都很有教育意义。

2 个答案:

答案 0 :(得分:1)

您可以使用箭头函数return 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
}));

答案 1 :(得分: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 }; 
    },
);

如果您真的需要减速器来确定默认值,您可以随时创建两个动作创建器并让您的包装器选择要触发的:

// 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函数返回的typescript typedef完全省略了可选的params,但是这种方法应该允许你在actionCreators中使用可选的params。