【问题标题】:Flow type does not apply to outer scope variables within an anonymous function流类型不适用于匿名函数中的外部范围变量
【发布时间】:2018-02-16 10:06:19
【问题描述】:

我为分发给减速器的动作定义了一个类型:

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

type QuestionAction =
  | RemoveQuestionAction
  | ...

reducer 检查每个动作的类型:

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),
    };    
  }

为什么我不能直接使用action 的值?

这是REPL

它在 REPL 中按预期执行,真的很奇怪,因为我看不出有什么不同..

Flow 是 6.23 版

【问题讨论】:

  • 我无法复制这个。你能在 Flow.org 上整理一个 REPL 来演示这个问题吗?我的测试按预期工作(不幸的是,我无法链接到它,因为 URL 太长,无法发表评论,而且 SO 不允许来自缩短器的 URL。
  • 可能与细化失效有关。 flow.org/en/docs/lang/refinements您使用的是哪个版本的流?
  • @ShuheiKagawa 可能是这样,但我不明白为什么 REPL 中的版本会这样
  • REPL 有效,因为QuestionAction 只有一种类型。 type QuestionAction = | RemoveQuestionAction | { type: 'FOO' } 会给你一个错误。

标签: javascript reactjs ecmascript-6 redux flowtype


【解决方案1】:

action.questionIdthe doc for type refinement 中解释的细化失效而引发错误。当filter()的箭头函数在case REMOVE_QUESTION:细化后执行时,Flow不确定action是否仍然是RemoveQuestionAction

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多