Flow不理解null或undefined的检查

问题描述 投票:0回答:2

现在我正在使用Apollo Codegen生成的Flow类型。这是非常有用的工具,但所有类型都是“可能”的。现在我有下一个问题:请考虑非常简化和简单的例子(链接到Flow try):

/* @flow */
type Type1 = {|  // <- example of Flow-type generated by Apollo Codegen
  prop?: ?string
|}

type Type2 = { // <- example of my Flow-type
  prop: string
}

function bar(y: Type2): void {
  console.log(y.prop)
}

function foo(x: Type1): void {
  if (x && x.prop && typeof x.prop === 'string') { // <- I'm trying to check the "x" argument
    bar(x)
  }
}

foo({ prop: 'hello' })

由于nullundefined,Flow无法理解我的检查并显示错误。如何管理?

javascript flowtype
2个回答
2
投票

这不能作为类型细化的原因是你的支票可以传递给Type1Type2。 Flow执行条件检查,但检查可以传递Type1的值,因此条件根本不会改进x的类型。然后在条件内,它看到你试图将Type1的值传递给Type2

要理解Flow的类型细化,重要的是要记住Flow不会对除变量类型之外的变量携带额外的细化数据。 Here是一个类似于你的例子,但没有可选字段。在valid函数中,我们检查y.field的类型,然后在我们知道它的类型后使用y.field。在invalid函数中,我们检查y.field的类型,然后尝试使用y。但是类型细化并没有改变y的类型,只有y.field,所以我们得到一个类型错误。

作为一个对应点,here是一个例子,我们根据字段的值进行类型细化。值得注意的是,在f函数内部,变量z具有Baz | Qux类型,并且我们的细化是在这两者之间不重叠的场上。在这种情况下,细化将类型Baz | Qux转换为类型Baz,我们可以无错误地调用我们的第二个函数。

为了解决这种局限,我们需要细分值x并将我们正在提炼的字段放入自己的变量中。然后,一旦我们知道了这个变量的类型,我们就会创建一个我们知道的类型为Type2的值,并将其传递给所需的函数。 Here是最直接的方式。

因为这种事情经常出现,我有一种创建“转换”功能的模式,可以将潜在的不干净数据转换为干净的数据,这样其他功能就不必为复杂的复杂性而烦恼。在这种情况下,我会这样做this

当清理深层嵌套数据或将嵌套对象从类型mixed转换为已知类型时,这种分解转换函数的模式也非常有用。通过组合小类型的转换对象而不是从头开始编写转换对象,更容易为大类型创建转换函数。


0
投票

在这个例子中,你正在改进属性prop的类型,你不是在改进x。流程中的细化只能用于顶级类型。有关其他策略,请参阅this question

© www.soinside.com 2019 - 2024. All rights reserved.