流创建自定义承诺类型



好吧,在我的应用程序中,我正在尝试将流类型添加到帆的水线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
};

(游乐场(

最新更新