流程创建自定义承诺类型

问题描述 投票:0回答:1

在我的应用程序中,我试图将流类型添加到Sail的水线orm。

为此,我尝试添加一个新类“ _DeferredPromise”,它是一个thenable(或promise,因为它正在使用promise.all并等待),但是它添加了一些额外的功能来允许链接数据库查询。 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
}

问题是:我似乎无法让流程像那些延迟的诺言诺言那样起作用,只是增加了一些附加功能。我尝试用$Exact<Promise>添加Promise签名-这使流程抱怨您无法做出确切的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兼容?

[例如,在尝试Flow中(我注意到那里的错误消息有所不同):fiddle

javascript promise flowtype
1个回答
0
投票

Flow为Promise提供了特殊处理,并且当前不允许您将await与自定义的Thenable一起使用。但是,您可以扩展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
};

([playground

要解决该问题,您实际上可以定义这样的类。不利之处在于,如果您只是尝试将类型添加到现有代码库中,则可能无法以实用的方式进行结构化:

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

([playground

© www.soinside.com 2019 - 2024. All rights reserved.