流量类型检查:如何迭代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 
}; 
+0

谢谢罗斯。不幸的是,这似乎并没有摆脱这个错误。 – yourfavorite

+0

@yourfavorite除了上述更改,请尝试从我的答案https://*.com/a/44640430/368697 –

+0

我无法弄清楚你的例子的哪个部分将解决这个问题,但我想出了如何解决flow.org/try上的错误感谢你的例子。我创建了一个没有错误的流,但现在的问题是当状态另一部分的操作被触发时,它会导致TypeError,因为它与我的两个actionType中的任何一个都不匹配。我将为此创建一个新的SO问题,因为这是一个不同的问题。我正在用这个解决方案创建一个新的答案,希望它可以在未来帮助其他人。谢谢你的帮助! – yourfavorite