【问题标题】:Using Flow union types for Redux actions为 Redux 操作使用 Flow 联合类型
【发布时间】:2017-04-12 17:41:54
【问题描述】:

按照this Facebook app sample的风格,同时使用Redux和Flow,我这样做了一个动作类型:

type Action =
  | { type: 'ADD_FILES', files: Array<{ id: number, file: File }> }
  | { type: 'HANDLE_IMAGE_PUBLISHED', id: number, name: string }
  | { type: 'SET_IMAGE_UPLOAD_PROGRESS', id: number, progress: number }
;

但我发现,当我尝试使用 reducer 处理我的操作时,如果我尝试访问 nameprogress 属性,Flow 会抱怨“在对象类型中找不到属性”。

也就是说,在我的减速器中,如果我检查 action.type === 'HANDLE_IMAGE_PUBLISHED' 然后访问 action.name,Flow 会抱怨。在action.type === 'SET_IMAGE_UPLOAD_PROGRESS' 时访问action.progress 属性也是如此。据我所知,这两种属性访问在各自的情况下都应该是合法的,但 Flow 抱怨道。

但由于某种原因,我可以在任何地方访问action.id,即使我的联合中的一种类型没有指定id 属性。我很困惑。

Here is a live demo in the Flow REPL。我做错了什么?

【问题讨论】:

    标签: redux flowtype


    【解决方案1】:

    这只是类型细化失效的一个例子:

    https://flow.org/en/docs/lang/refinements/#toc-refinement-invalidations

    因为您在回调中使用该值,Flow 悲观地假设您可以在回调运行之前重新分配 action(它不知道立即调用 map 回调)。它也不会进行分析以查看实际上没有位置可以重新分配它。

    只需将action 拉出为const

    export default (state: Array<ImageRecordModel> = [], action_: Action): Array<ImageRecordModel> => {
      const action = action_;
    

    (tryflow link)

    您可能还需要考虑在 .flowconfig 中启用 const 参数。这基本上符合您的期望:将所有参数视为const

    [options]
    experimental.const_params=true
    

    【讨论】:

    • 我明白了,谢谢你的解释。我想使用 experimental.const_params=true 是有意义的,因为我也在使用 ESLint 的 no-param-reassign 规则。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多