javascript - 流: check type of thenable

标签 javascript flowtype

我有一个函数接受 thenable(具有 then() 方法的对象;参见 MDN JavaScript docs: Promise.resolve() 的顶部)或其他:

function resolve<T>(value: {then: ()=>T}|T) {
    if (value && value.then) {
        console.log('thenable', value.then);
    } else {
        console.log('not thenable');
    }
}

Try Flow demo

当我在此 if 语句中访问 value.then 时,Flow 会报错。我可以用 (value: any).then 修复它,但这看起来很老套。

谁能推荐一种类型检查的好方法?

最佳答案

好问题!这是 Flow 团队在过去几周一直在努力解决的问题!

问题是什么

if (value && value.then) {
  // What is the type of `value` here?
} else

在 if 语句中,value 的类型是什么?如果 Tstring,那么它将是 {then: ()=>T},如您所料。但是如果 T{ then: string } 呢?据我们所知,T 可能有一个名为 then 的属性!

Flow 团队正在做什么来解决这个问题?

  • 添加确切的对象类型。这个问题来自不知道工会的一个分支是否可能拥有属性(property)。使用确切的类型,您可以准确地告诉 Flow 一个对象具有哪些属性。
  • 允许value.then属性检查,并将value.then的类型细化为mixed

其中很多工作已经在 master 中了。您可以查看 flowtype.org/try,它目前由 master 运行。 Your example on flowtype.org/try

一旦这些东西落地(一些出现在 v0.31.0 中,一些出现在 v0.32.0 中),我们将对其进行记录和博客。

编辑:添加更多信息

3个主要问题

我们正在努力解决 3 个一般性问题。

  • 我们什么时候应该在条件语句中允许value.then?如果我们只允许 value.then 当我们确定 value 有一个 then 属性时,那么我们可以捕获像 value 这样的拼写错误.tehn。但是,惯用的 JavaScript 经常测试对象中可能存在或不存在的属性。
  • 如果条件为真或假, 的类型是什么。在提供的示例中,value 是联合类型。看起来 value && value.then 的目的是检测函数是否正在使用联合的左分支。然而,Flow 不能安全地选择一个分支,因为 T 可能有一个 then 字段。
  • 如果条件为真或假,value.then 的类型是什么。同样,T 可能是一个像 { then: string } 这样的对象,所以 value.then 可能是任何东西

我们的解决方案

When should we allow value.then in a conditional

我们将始终允许 value.then。这意味着我们不能轻易捕获属性名称拼写错误,但这意味着我们可以支持更多地道的 JavaScript。 Flow 的主要原则之一是它可以很好地与人们倾向于编写的 JavaScript 配合使用。

What is the type of value if the conditional is true or false.

如果 Flow 确定联合类型中只有一个分支可以工作,它会将 value 的类型细化到该分支。否则,value 将不会被细化。精确类型将对此有所帮助

What is the type of value.then if the conditional is true or false

如果 Flow 确定只有联合类型的一个分支可以工作,它会将 value.then 的类型细化为 then 属性的类型那个分支。如果 Flow 确定没有分支具有该属性,它就会出错。否则,它将使用 mixed 类型。精确类型也有助于此。

什么是精确类型

{ x: string } 是具有 x 属性的对象类型,其类型为 string

var example1: { x: string } = { x: 'hello' }; // This is ok
var example2: { x: string } = { x: 'hello', y: 123 }; // This is also ok

这对于惯用的 JavaScript 很有用,但让 Flow 很难说一个对象类型没有属性。所以我们要添加精确类型。

{| x: string |} 是具有属性 x 的对象类型,其类型为 string 但没有其他属性。

var example1: {| x: string |} = { x: 'hello' }; // This is ok
var example2: {| x: string |} = { x: 'hello', y: 123 }; // Error! Extra property y!

这很有帮助,因为你可以这样写:

type Foo = {| x: string |} | {| y: string |};

function test(arg: Foo): string | void {
  if (arg.x) {
    return arg.x;
  }
}

一旦我们推出这些,我们将记录它们!所以请擦亮眼睛!

关于javascript - 流: check type of thenable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39018508/

相关文章:

javascript - 站点使用 jquery 和 wp_enqueue_script 显示空白屏幕

javascript - 在遍历 Object.entries 时,Flow 似乎假定了错误的类型

javascript - 如何帮助流程处理 react 组件状态初始化器?

javascript - 将 JavaScript 局部变量转换为全局变量

JavaScript 函数关闭(){}

javascript - 将对象推送到 Mongoose 数组并检查数组对象内的重复字段

javascript - Flow 无法识别过滤不可变列表

javascript - 如何修复以下 JavaScript 代码以使其与 Flowtype 一起使用?

javascript - Babel 不剥离流注解

magento - 是否真的需要 Magento 加载的所有默认脚本?