export type PromiseType = T extends Promise ? U : T; export type AsyncReturnType any> = PromiseType>; export abstract class ExtensiblePromise implements PromiseLike { constructor() { this.promise = new Promise((resolve, reject) => { this._reject = reject; this._resolve = resolve; }); } readonly promise: Promise; protected _resolve: (arg: T) => void; protected _reject: (reason?: any) => void; then( onfulfilled?: (value: T) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike ): Promise { return this.promise.then(onfulfilled, onrejected); } catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): Promise { return this.promise.catch(onrejected); } } /** * A Promise-Like class that can be controlled (resolved/rejected) via a public API */ export class ControlledPromise extends ExtensiblePromise { resolve(p?: T) { this._resolve(p); } reject(e?: any) { this._reject(e); } } export const delay = ms => new Promise(res => setTimeout(res, ms))