好吧,在我的应用程序中,我正在尝试将流类型添加到帆的水线orm中。
为此,我尝试添加一个新类"_DeferredPromise",这是一个thenable
(或promise
,因为它与promise.all和await一起工作(,但是它添加了一些额外的函数来允许链接数据库查询。ORM上表的典型签名是:
type DatabaseORMTy<T> = {
find: (number | {+[string]: mixed}) => _DeferredPromiseTy<$Array<T>>,
//...
}
和延期承诺:
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 表现得好像那些延迟的承诺是承诺,只是增加了一些附加功能。我尝试添加带有$Exact<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中(我注意到那里的错误消息不同(: 小提琴
Flow 提供了Promise
特殊处理,目前不允许您将await
与自定义 Thenables 一起使用。但是,您可以扩展Promise
,并且 Flow 允许您将子类的实例用作Promise
。
您有以下几种选择:
你可以使用declare class
,这让 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
};
(游乐场(