Javascript 流类型不适用于匿名函数内的外部作用域变量

Javascript 流类型不适用于匿名函数内的外部作用域变量,javascript,reactjs,ecmascript-6,redux,flowtype,Javascript,Reactjs,Ecmascript 6,Redux,Flowtype,我为调度到减速器的操作定义了一个类型: type RemoveQuestionAction = { type: 'REMOVE_QUESTION', questionId: number, docTypeId: number, }; type QuestionAction = | RemoveQuestionAction | ... 减速器检查每个动作的类型: const questions = ( state : QuestionState = defaultSta

我为调度到减速器的操作定义了一个类型:

type RemoveQuestionAction = {
  type: 'REMOVE_QUESTION',
  questionId: number,
  docTypeId: number,
};

type QuestionAction =
  | RemoveQuestionAction
  | ...
减速器检查每个动作的类型:

const questions = (
  state : QuestionState = defaultState,
  action : QuestionAction
) : QuestionState => {...};
字段questionId在两个数组筛选器中引用:

  case REMOVE_QUESTION: {

    return {
      ...state,
      byId: state.allIds
                             // Throws error
        .filter(id => id !== action.questionId)
        .reduce((col, id) => ({
          ...col,
          [id]: state.byId[String(id)],
        }), {}),
                                               // Throws error
      allIds: state.allIds.filter(id => id !== action.questionId),
    };    
  }
这会引发action.questionId的类型错误

但是,如果将操作的值放在变量中,则表示满意:

  case REMOVE_QUESTION: {
    let { questionId } = action; // Ok with this

    return {
      ...state,
      byId: state.allIds
        .filter(id => id !== questionId)
        .reduce((col, id) => ({
          ...col,
          [id]: state.byId[String(id)],
        }), {}),
      allIds: state.allIds.filter(id => id !== questionId),
    };    
  }
为什么我不能直接使用动作的值

这是一本书

它在REPL中的性能与预期一样,非常奇怪,因为我看不出有什么不同

流程版本为6.23

action.questionId由于中解释的细化无效而引发错误。在按大小写删除问题进行细化后执行指定给筛选器的箭头函数时,流不确定操作是否仍为RemoveQuestionAction:


我们人类知道过滤器会立即执行给定的回调函数,比如id=>id!==action.questionId,因此根本无法修改操作。然而,从流的角度来看,filter只是一个将回调函数作为参数的函数,回调函数可以像addEventListener那样稍后执行。如果回调函数可以稍后执行,则可能会修改操作,并且类型优化不再有效。这就是为什么在这种情况下,flow会使动作的类型细化无效。

我无法复制这一点。你能在Flow.org上创建一个REPL来演示这个问题吗?我的测试按预期工作,不幸的是,我无法链接到它,因为URL对于注释来说太长了,因此不允许来自缩写器的URL。这可能与细化失效有关。您使用的是哪个版本的flow?@ShuheiKagawa可能是,但我不明白为什么REPL中的版本会以REPL的方式工作,因为QuestionAction只有一种类型。类型QuestionAction=| RemoveQuestionAction |{type:'FOO'}将给您一个错误。