流量类型检查:如何迭代redux操作中可能未定义的属性?
问题描述:
我有一个Redux减速器的偏好设置,我使用流量类型检查器。我的减速器可以采取两种类型的动作。一个用于加载初始应用加载时发生的所有偏好。第二种操作类型发生在用户更新特定首选项时。这是我的减速机的代码。在那里我遇到的问题是,当我尝试做action.prefs.forEach
此时流动抛出一个错误说...'prefs': Property not found in 'object type'
流量类型检查:如何迭代redux操作中可能未定义的属性?
// @flow
import {
UPDATE_PREF,
LOAD_PREFS_SUCCESS
} from '../actions/prefs';
export type actionType = {
+type: string,
prefs: Array<{_id: string, value: any}>
} | {
+type: string,
id: string,
value: any
};
export default (state: stateType = {}, action: actionType) => {
switch (action.type) {
case LOAD_PREFS_SUCCESS: {
const newState = {};
action.prefs.forEach(p => {
newState[p._id] = p.value;
});
return newState;
}
case UPDATE_PREF: {
return { ...state, [action.id]: action.value };
}
default:
return state;
}
};
正如你可以看到我有两种类型的操作。加载所有首选项时,该操作具有一系列首选项。 [ { _id: 'color', value: 'blue' } ]
当更新一个首选项时,我得到一个id和一个值。所以,给我两个具有不同属性的动作类型,我如何获得流动来避免在动作流类型中抛出这种变化的错误?
答
由于一些指导从@罗斯 - 阿伦和一些对flow.org玩弄我已经找到了working solution。
它的缺点是,除了罗斯的回答加入+type: UPDATE_PREF
,我还需要加typeof
。所以工作actionType是:
export type actionType = {
+type: typeof LOAD_PREFS_SUCCESS,
prefs: Array<{_id: string, value: any}>
} | {
+type: typeof UPDATE_PREF,
id: string,
value: any
};
再次感谢@ ross-allen。
答
为了说明Flow在disjoint union中选择哪种类型,+type
必须是值而不是string
。更改actionType
使用值:
// @flow
import {
UPDATE_PREF,
LOAD_PREFS_SUCCESS
} from '../actions/prefs';
export type actionType = {
+type: LOAD_PREFS_SUCCESS, // not just `string`
prefs: Array<{_id: string, value: any}>
} | {
+type: UPDATE_PREF, // not just `string`
id: string,
value: any
};
谢谢罗斯。不幸的是,这似乎并没有摆脱这个错误。 – yourfavorite
@yourfavorite除了上述更改,请尝试从我的答案https://stackoverflow.com/a/44640430/368697 –
我无法弄清楚你的例子的哪个部分将解决这个问题,但我想出了如何解决flow.org/try上的错误感谢你的例子。我创建了一个没有错误的流,但现在的问题是当状态另一部分的操作被触发时,它会导致TypeError,因为它与我的两个actionType中的任何一个都不匹配。我将为此创建一个新的SO问题,因为这是一个不同的问题。我正在用这个解决方案创建一个新的答案,希望它可以在未来帮助其他人。谢谢你的帮助! – yourfavorite