在我的应用程序中,我尝试向 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
};
为了解决这个问题,您实际上可以定义这样一个类。这里的缺点是,如果您只是尝试向现有代码库添加类型,则它的结构可能不实用:
class _DeferredPromiseTy<T> extends Promise<T> {
fetch(): _DeferredPromiseTy<T> { return this; }
limit(x: string|number): _DeferredPromiseTy<T> { return this; }
//and more
};
关于javascript - Flow 制作自定义 promise 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59757224/