export interface CallablePromise < T , U > { ( ... args ) : Promise < T > ; } export class ExtensibleFunction { constructor ( f ) { return Object . setPrototypeOf ( f , new . target . prototype ) ; } } export class CallablePromise < T , U > extends ExtensibleFunction { private res : ( value ? : T | PromiseLike < T > ) => void = undefined as any ; private rej : ( reason ? : any ) => void = undefined as any ; private promise : Promise < T > = undefined as any ; private args : U [ ] = [ ] ; private executor : ( args : U [ ] , resolve : ( value ? : T | PromiseLike < T > ) => void , reject : ( reason ? : any ) => void ) => void ; private isExecuted = false ; constructor ( executor ) { super ( ( ... args ) => { this . args = args ; return this ; } ) ; this . executor = executor ; } execute ( ) { this . isExecuted = true ; this . promise = new Promise ( ( resolve , reject ) => { this . res = resolve ; this . rej = reject ; this . executor ( this . args , resolve , reject ) ; } ) ; } then ( onfulfilled ? , onrejected ? ) { if ( ! this . isExecuted ) this . execute ( ) ; return this . promise . then ( onfulfilled , onrejected ) ; } catch ( onRejected ? ) { if ( ! this . isExecuted ) this . execute ( ) ; return this . promise . catch ( onRejected ) ; } }