javascript - Flow 制作自定义 promise 类型

标签 javascript promise flowtype

在我的应用程序中,我尝试向 sail 的水线 orm 添加流类型。

为此,我尝试添加一个新类“_DeferredPromise”,它是 thenable (或 promise ,因为它与promise.all和await一起使用),但是它添加了一些额外的函数以允许链接数据库查询。 ORM 上表的典型签名是:

type DatabaseORMTy<T> = {
  find: (number | {+[string]: mixed}) => _DeferredPromiseTy<$Array<T>>,
  //...
}

和 deferredPromise:

type _DeferredPromiseTy<T> = {
  ...Promise<T>,
  fetch: () => _DeferredPromiseTy<T>,
  limit: (string|number) => _DeferredPromiseTy<T>,
  select: (?$ReadOnlyArray<string>) => _DeferredPromiseTy<T>,
  skip: (number) => _DeferredPromiseTy<T>,
  sort: (string) => _DeferredPromiseTy<T>,
  //and more
}

问题是:我似乎无法让 Flow 表现得就像这些延迟 promise promise 一样,只是带有一些附加功能。我尝试使用 $Exact<Promise> 添加 promise 签名- 这让 Flow 提示你无法做出准确的 promise 。我尝试使用 = Promise & {...} 添加它们我在上面尝试过。

但是这些都显示使用错误:

const data:T = await myTable.find(1).limit(1); //would find the entry with id=1, and at most 1 entry.

出现以下错误:

Error: Cannot call await with `find(...)` bound to `p` because  `_DeferredPromiseTy` [1] is incompatible with  `Promise` [2].

如何使自定义类型与 Promise 兼容?

一个例子,在 try Flow 中(我注意到那里的错误消息是不同的): fiddle

最佳答案

Flow 给予 Promise 特殊处理,目前不允许您将 await 与自定义 Thenable 一起使用。但是,您可以扩展 Promise,Flow 允许您将子类的实例用作 Promise

您有几个选择:

您可以使用声明类,这使 Flow 认为存在该类型的类可用。这里的缺点是 Flow 将允许您执行诸如 x instanceof _DeferredPromiseTy 之类的操作,或尝试构造它,即使现实中实际上不存在任何这样的类。

declare class _DeferredPromiseTy<T> extends Promise<T> {
  fetch: () => _DeferredPromiseTy<T>,
  limit: (string|number) => _DeferredPromiseTy<T>,
  select: (?$ReadOnlyArray<string>) => _DeferredPromiseTy<T>,
  skip: (number) => _DeferredPromiseTy<T>,
  sort: (string) => _DeferredPromiseTy<T>,
  //and more
};

(playground)

为了解决这个问题,您实际上可以定义这样一个类。这里的缺点是,如果您只是尝试向现有代码库添加类型,则它的结构可能不实用:

class _DeferredPromiseTy<T> extends Promise<T> {
  fetch(): _DeferredPromiseTy<T> { return this; }
  limit(x: string|number): _DeferredPromiseTy<T> { return this; }
  //and more
};

(playground)

关于javascript - Flow 制作自定义 promise 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59757224/

相关文章:

javascript - 将流类型注释提取到外部文件中

javascript - 使用 ES6 + Flow 代替 TypeScript

javascript - 如何从视频标签的媒体播放器中删除/隐藏仅播放/暂停图标/按钮

javascript - FineUploader批量上传一个无效对象

javascript - Promise.all 中的 promise 多次被拒绝,到底发生了什么?

javascript - 在 promise 中运行同步功能

javascript - 如何从 mocha.opts 文件中正确地要求模块

javascript - 小 slider 点击监听器注册太晚

javascript - NodeJS - 循环内的延迟函数

flowtype - 如何使用 Flow 类型检查器扩展数组?