From 0527215077a0ae96a601d756f723b5e04617716e Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Thu, 22 Jan 2015 15:39:03 +1300 Subject: [PATCH 1/3] Increase test coverage of when Checks all variations of up to 3 argument versions of variadic functions along with the 5 argument version. Should ensure implementation is pretty close to required. --- when/when-tests.ts | 73 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/when/when-tests.ts b/when/when-tests.ts index d90ab69bd..9e949dad9 100644 --- a/when/when-tests.ts +++ b/when/when-tests.ts @@ -18,9 +18,6 @@ var foreign = new ForeignPromise(1); var error = new Error("boom!"); var example: () => void; -// TODO: with TypeScript 1.4 a lot of these functions should change to use PromiseOrValue -// type PromiseOrValue = Promise | T; - /* * * * * * * * Core * * * * * * * */ @@ -58,14 +55,37 @@ promise = when.attempt((a: number, b: number, c: number) => a + b + c, 1, when(2 promise = when.attempt((a: number, b: number, c: number) => a + b + c, when(1), 2, when(3)); promise = when.attempt((a: number, b: number, c: number) => a + b + c, when(1), when(2), when(3)); +promise = when.attempt((a: number, b: number, c: number, d: number, e: number) => a + b + c + d + e, when(1), when(2), when(3), when(4), when(5)); + /* when.lift(f) */ -// TODO: This is the major issue with lack of union types, it's not possible to represent the return type of when.lift without them. +var liftedFunc0 = when.lift(() => 2); +var liftedFunc1 = when.lift((a: number) => a + a); +var liftedFunc2 = when.lift((a: number, b: number) => a + b); +var liftedFunc3 = when.lift((a: number, b: number, c: number) => a + b + c); -var liftedFunc0: () => when.Promise = when.lift(() => 2); -var liftedFunc1: (a: when.Promise) => when.Promise = when.lift((a: number) => a + a); -var liftedFunc2: (a: when.Promise, b: when.Promise) => when.Promise = when.lift((a: number, b: number) => a + b); -var liftedFunc3: (a: when.Promise, b: when.Promise, c: when.Promise) => when.Promise = when.lift((a: number, b: number, c: number) => a + b + c); +var liftedFunc5 = when.lift((a: number, b: number, c: number, d: number, e: number) => a + b + c + d + e); + +promise = liftedFunc0(); + +promise = liftedFunc1(1); +promise = liftedFunc1(when(1)); + +promise = liftedFunc2(1, 2); +promise = liftedFunc2(when(1), 2); +promise = liftedFunc2(1, when(2)); +promise = liftedFunc2(when(1), when(2)); + +promise = liftedFunc3(1, 2, 3); +promise = liftedFunc3(when(1), 2, 3); +promise = liftedFunc3(1, when(2), 3); +promise = liftedFunc3(when(1), when(2), 3); +promise = liftedFunc3(1, 2, when(3)); +promise = liftedFunc3(when(1), 2, when(3)); +promise = liftedFunc3(1, when(2), when(3)); +promise = liftedFunc3(when(1), when(2), when(3)); + +promise = liftedFunc5(when(1), when(2), when(3), when(4), when(5)); /* when.join(...promises) */ @@ -196,17 +216,40 @@ import nodefn = require('when/node'); /* node.lift */ -// TODO: Again it's not possible to represent the return type of node.lift without union types. - var nodeFn0 = (callback: (err: any, result: number) => void) => callback(null, 0); var nodeFn1 = (a: number, callback: (err: any, result: number) => void) => callback(null, a); var nodeFn2 = (a: number, b: number, callback: (err: any, result: number) => void) => callback(null, a + b); var nodeFn3 = (a: number, b: number, c: number, callback: (err: any, result: number) => void) => callback(null, a + b + c); -var promiseFunc0: () => when.Promise = nodefn.lift(nodeFn0); -var promiseFunc1: (a: when.Promise) => when.Promise = nodefn.lift(nodeFn1); -var promiseFunc2: (a: when.Promise, b: when.Promise) => when.Promise = nodefn.lift(nodeFn2); -var promiseFunc3: (a: when.Promise, b: when.Promise, c: when.Promise) => when.Promise = nodefn.lift(nodeFn3); +var nodeFn5 = (a: number, b: number, c: number, d: number, e: number, callback: (err: any, result: number) => void) => callback(null, a + b + c + d + e); + +var liftedNodeFunc0 = nodefn.lift(nodeFn0); +var liftedNodeFunc1 = nodefn.lift(nodeFn1); +var liftedNodeFunc2 = nodefn.lift(nodeFn2); +var liftedNodeFunc3 = nodefn.lift(nodeFn3); + +var liftedNodeFunc5 = nodefn.lift(nodeFn5); + +promise = liftedNodeFunc0(); + +promise = liftedNodeFunc1(1); +promise = liftedNodeFunc1(when(1)); + +promise = liftedNodeFunc2(1, 2); +promise = liftedNodeFunc2(when(1), 2); +promise = liftedNodeFunc2(1, when(2)); +promise = liftedNodeFunc2(when(1), when(2)); + +promise = liftedNodeFunc3(1, 2, 3); +promise = liftedNodeFunc3(when(1), 2, 3); +promise = liftedNodeFunc3(1, when(2), 3); +promise = liftedNodeFunc3(when(1), when(2), 3); +promise = liftedNodeFunc3(1, 2, when(3)); +promise = liftedNodeFunc3(when(1), 2, when(3)); +promise = liftedNodeFunc3(1, when(2), when(3)); +promise = liftedNodeFunc3(when(1), when(2), when(3)); + +promise = liftedNodeFunc5(when(1), when(2), when(3), when(4), when(5)); example = function() { var resolveAddress = nodefn.lift(dns.resolve); @@ -285,6 +328,8 @@ promise = nodefn.call(nodeFn3, 1, when(2), when(3)); promise = nodefn.call(nodeFn3, when(1), 2, when(3)); promise = nodefn.call(nodeFn3, when(1), when(2), when(3)); +promise = nodefn.call(nodeFn5, when(1), when(2), when(3), when(4), when(5)); + example = function () { var loadPasswd = nodefn.call(fs.readFile, '/etc/passwd'); From 484aff0c24ab85ba79817031cdff96e884fa99ca Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Thu, 22 Jan 2015 15:47:50 +1300 Subject: [PATCH 2/3] Use disparate types to more constrain impl --- when/when-tests.ts | 136 ++++++++++++++++++++++----------------------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/when/when-tests.ts b/when/when-tests.ts index 9e949dad9..61b688a03 100644 --- a/when/when-tests.ts +++ b/when/when-tests.ts @@ -41,51 +41,51 @@ promise = when.attempt(() => 1); promise = when.attempt((a: number) => a + a, 1); promise = when.attempt((a: number) => a + a, when(1)); -promise = when.attempt((a: number, b: number) => a + b, 1, 2); -promise = when.attempt((a: number, b: number) => a + b, 1, when(2)); -promise = when.attempt((a: number, b: number) => a + b, when(1), 2); -promise = when.attempt((a: number, b: number) => a + b, when(1), when(2)); +promise = when.attempt((a: number, b: string) => a, 1, '2'); +promise = when.attempt((a: number, b: string) => a, 1, when('2')); +promise = when.attempt((a: number, b: string) => a, when(1), '2'); +promise = when.attempt((a: number, b: string) => a, when(1), when('2')); -promise = when.attempt((a: number, b: number, c: number) => a + b + c, 1, 2, 3); -promise = when.attempt((a: number, b: number, c: number) => a + b + c, 1, when(2), 3); -promise = when.attempt((a: number, b: number, c: number) => a + b + c, when(1), 2, 3); -promise = when.attempt((a: number, b: number, c: number) => a + b + c, when(1), when(2), 3); -promise = when.attempt((a: number, b: number, c: number) => a + b + c, 1, 2, when(3)); -promise = when.attempt((a: number, b: number, c: number) => a + b + c, 1, when(2), when(3)); -promise = when.attempt((a: number, b: number, c: number) => a + b + c, when(1), 2, when(3)); -promise = when.attempt((a: number, b: number, c: number) => a + b + c, when(1), when(2), when(3)); +promise = when.attempt((a: number, b: string, c: boolean) => a, 1, '2', true); +promise = when.attempt((a: number, b: string, c: boolean) => a, 1, when('2'), true); +promise = when.attempt((a: number, b: string, c: boolean) => a, when(1), '2', true); +promise = when.attempt((a: number, b: string, c: boolean) => a, when(1), when('2'), true); +promise = when.attempt((a: number, b: string, c: boolean) => a, 1, '2', when(true)); +promise = when.attempt((a: number, b: string, c: boolean) => a, 1, when('2'), when(true)); +promise = when.attempt((a: number, b: string, c: boolean) => a, when(1), '2', when(true)); +promise = when.attempt((a: number, b: string, c: boolean) => a, when(1), when('2'), when(true)); -promise = when.attempt((a: number, b: number, c: number, d: number, e: number) => a + b + c + d + e, when(1), when(2), when(3), when(4), when(5)); +promise = when.attempt((a: number, b: string, c: boolean, d: number, e: string) => a, when(1), when('2'), when(true), when(4), when('5')); /* when.lift(f) */ -var liftedFunc0 = when.lift(() => 2); -var liftedFunc1 = when.lift((a: number) => a + a); -var liftedFunc2 = when.lift((a: number, b: number) => a + b); -var liftedFunc3 = when.lift((a: number, b: number, c: number) => a + b + c); +var liftedFunc0 = when.lift(() => 0); +var liftedFunc1 = when.lift((a: number) => a); +var liftedFunc2 = when.lift((a: number, b: string) => a); +var liftedFunc3 = when.lift((a: number, b: string, c: boolean) => a); -var liftedFunc5 = when.lift((a: number, b: number, c: number, d: number, e: number) => a + b + c + d + e); +var liftedFunc5 = when.lift((a: number, b: string, c: boolean, d: number, e: string) => a); promise = liftedFunc0(); promise = liftedFunc1(1); promise = liftedFunc1(when(1)); -promise = liftedFunc2(1, 2); -promise = liftedFunc2(when(1), 2); -promise = liftedFunc2(1, when(2)); -promise = liftedFunc2(when(1), when(2)); +promise = liftedFunc2(1, '2'); +promise = liftedFunc2(when(1), '2'); +promise = liftedFunc2(1, when('2')); +promise = liftedFunc2(when(1), when('2')); -promise = liftedFunc3(1, 2, 3); -promise = liftedFunc3(when(1), 2, 3); -promise = liftedFunc3(1, when(2), 3); -promise = liftedFunc3(when(1), when(2), 3); -promise = liftedFunc3(1, 2, when(3)); -promise = liftedFunc3(when(1), 2, when(3)); -promise = liftedFunc3(1, when(2), when(3)); -promise = liftedFunc3(when(1), when(2), when(3)); +promise = liftedFunc3(1, '2', true); +promise = liftedFunc3(when(1), '2', true); +promise = liftedFunc3(1, when('2'), true); +promise = liftedFunc3(when(1), when('2'), true); +promise = liftedFunc3(1, '2', when(true)); +promise = liftedFunc3(when(1), '2', when(true)); +promise = liftedFunc3(1, when('2'), when(true)); +promise = liftedFunc3(when(1), when('2'), when(true)); -promise = liftedFunc5(when(1), when(2), when(3), when(4), when(5)); +promise = liftedFunc5(when(1), when('2'), when(true), when(4), when('5')); /* when.join(...promises) */ @@ -133,16 +133,16 @@ promise = when(1).then((val: number) => when(val + val), (err: any) => 2); /* promise.spread(onFulfilledArray) */ // TODO: Work out how to do this... -// promise = when([1, 2, 3]).spread((a: number, b: number) => a + b); -// promise = when([1, 2, 3]).spread((a: number, b: number) => when(a + b)); +// promise = when([1, '2', true]).spread((a: number, b: string, c: boolean) => a); +// promise = when([1, '2', true]).spread((a: number, b: string, c: boolean) => when(a)); /* promise.fold(combine, promise2) */ -promise = when(1).fold((a: number, b: number) => a + b, 2); -promise = when(1).fold((a: number, b: number) => a + b, when(2)); +promise = when(1).fold((a: number, b: string) => a, '2'); +promise = when(1).fold((a: number, b: string) => a, when('2')); -promise = when(1).fold((a: number, b: number) => when(a + b), 2); -promise = when(1).fold((a: number, b: number) => when(a + b), when(2)); +promise = when(1).fold((a: number, b: string) => when(a), '2'); +promise = when(1).fold((a: number, b: string) => when(a), when('2')); /* promise.catch(onRejected) */ @@ -218,10 +218,10 @@ import nodefn = require('when/node'); var nodeFn0 = (callback: (err: any, result: number) => void) => callback(null, 0); var nodeFn1 = (a: number, callback: (err: any, result: number) => void) => callback(null, a); -var nodeFn2 = (a: number, b: number, callback: (err: any, result: number) => void) => callback(null, a + b); -var nodeFn3 = (a: number, b: number, c: number, callback: (err: any, result: number) => void) => callback(null, a + b + c); +var nodeFn2 = (a: number, b: string, callback: (err: any, result: number) => void) => callback(null, a); +var nodeFn3 = (a: number, b: string, c: boolean, callback: (err: any, result: number) => void) => callback(null, a); -var nodeFn5 = (a: number, b: number, c: number, d: number, e: number, callback: (err: any, result: number) => void) => callback(null, a + b + c + d + e); +var nodeFn5 = (a: number, b: string, c: boolean, d: number, e: string, callback: (err: any, result: number) => void) => callback(null, a); var liftedNodeFunc0 = nodefn.lift(nodeFn0); var liftedNodeFunc1 = nodefn.lift(nodeFn1); @@ -235,21 +235,21 @@ promise = liftedNodeFunc0(); promise = liftedNodeFunc1(1); promise = liftedNodeFunc1(when(1)); -promise = liftedNodeFunc2(1, 2); -promise = liftedNodeFunc2(when(1), 2); -promise = liftedNodeFunc2(1, when(2)); -promise = liftedNodeFunc2(when(1), when(2)); +promise = liftedNodeFunc2(1, '2'); +promise = liftedNodeFunc2(when(1), '2'); +promise = liftedNodeFunc2(1, when('2')); +promise = liftedNodeFunc2(when(1), when('2')); -promise = liftedNodeFunc3(1, 2, 3); -promise = liftedNodeFunc3(when(1), 2, 3); -promise = liftedNodeFunc3(1, when(2), 3); -promise = liftedNodeFunc3(when(1), when(2), 3); -promise = liftedNodeFunc3(1, 2, when(3)); -promise = liftedNodeFunc3(when(1), 2, when(3)); -promise = liftedNodeFunc3(1, when(2), when(3)); -promise = liftedNodeFunc3(when(1), when(2), when(3)); +promise = liftedNodeFunc3(1, '2', true); +promise = liftedNodeFunc3(when(1), '2', true); +promise = liftedNodeFunc3(1, when('2'), true); +promise = liftedNodeFunc3(when(1), when('2'), true); +promise = liftedNodeFunc3(1, '2', when(true)); +promise = liftedNodeFunc3(when(1), '2', when(true)); +promise = liftedNodeFunc3(1, when('2'), when(true)); +promise = liftedNodeFunc3(when(1), when('2'), when(true)); -promise = liftedNodeFunc5(when(1), when(2), when(3), when(4), when(5)); +promise = liftedNodeFunc5(when(1), when('2'), when(true), when(4), when('5')); example = function() { var resolveAddress = nodefn.lift(dns.resolve); @@ -314,21 +314,21 @@ promise = nodefn.call(nodeFn0); promise = nodefn.call(nodeFn1, 1); promise = nodefn.call(nodeFn1, when(1)); -promise = nodefn.call(nodeFn2, 1, 2); -promise = nodefn.call(nodeFn2, 1, when(2)); -promise = nodefn.call(nodeFn2, when(1), 2); -promise = nodefn.call(nodeFn2, when(1), when(2)); +promise = nodefn.call(nodeFn2, 1, '2'); +promise = nodefn.call(nodeFn2, 1, when('2')); +promise = nodefn.call(nodeFn2, when(1), '2'); +promise = nodefn.call(nodeFn2, when(1), when('2')); -promise = nodefn.call(nodeFn3, 1, 2, 3); -promise = nodefn.call(nodeFn3, 1, when(2), 3); -promise = nodefn.call(nodeFn3, when(1), 2, 3); -promise = nodefn.call(nodeFn3, when(1), when(2), 3); -promise = nodefn.call(nodeFn3, 1, 2, when(3)); -promise = nodefn.call(nodeFn3, 1, when(2), when(3)); -promise = nodefn.call(nodeFn3, when(1), 2, when(3)); -promise = nodefn.call(nodeFn3, when(1), when(2), when(3)); +promise = nodefn.call(nodeFn3, 1, '2', true); +promise = nodefn.call(nodeFn3, 1, when('2'), true); +promise = nodefn.call(nodeFn3, when(1), '2', true); +promise = nodefn.call(nodeFn3, when(1), when('2'), true); +promise = nodefn.call(nodeFn3, 1, '2', when(true)); +promise = nodefn.call(nodeFn3, 1, when('2'), when(true)); +promise = nodefn.call(nodeFn3, when(1), '2', when(true)); +promise = nodefn.call(nodeFn3, when(1), when('2'), when(true)); -promise = nodefn.call(nodeFn5, when(1), when(2), when(3), when(4), when(5)); +promise = nodefn.call(nodeFn5, when(1), when('2'), when(true), when(4), when('5')); example = function () { var loadPasswd = nodefn.call(fs.readFile, '/etc/passwd'); @@ -340,7 +340,7 @@ example = function () { /* node.apply */ -promise = nodefn.apply(nodeFn2, [1, 2]); +promise = nodefn.apply(nodeFn2, [1, '2']); example = function () { var loadPasswd = nodefn.apply(fs.readFile, ['/etc/passwd']); @@ -375,7 +375,7 @@ example = function () { example = function () { when.promise((resolve, reject) => - nodeFn2(1, 2, nodefn.createCallback({ resolve: resolve, reject: reject }))) + nodeFn2(1, '2', nodefn.createCallback({ resolve: resolve, reject: reject }))) .then( (value: number) => console.log(value), (err: any) => console.error(err)); From 892d67aa032480f04e988ab23d37ef834507f46f Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Thu, 22 Jan 2015 16:46:16 +1300 Subject: [PATCH 3/3] Use helper interfaces and unions to define variadic functions up to 5 arguments --- when/when.d.ts | 203 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 132 insertions(+), 71 deletions(-) diff --git a/when/when.d.ts b/when/when.d.ts index 5db15b316..be5e25f15 100644 --- a/when/when.d.ts +++ b/when/when.d.ts @@ -12,29 +12,79 @@ declare function When(value: When.Thenable, transform: (val: T) => U): declare function When(value: T, transform: (val: T) => U): When.Promise; declare module When { - function attempt(f: () => T): Promise; + // Helper interfaces + module _ { + interface Fn0 { (): T } + interface Fn1 { (a1: A1): T } + interface Fn2 { (a1: A1, a2: A2): T } + interface Fn3 { (a1: A1, a2: A2, a3: A3): T } + interface Fn4 { (a1: A1, a2: A2, a3: A3, a4: A4): T } + interface Fn5 { (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): T } + interface Fn6 { (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6): T } - function attempt(f: (a: A) => T, a: Promise): Promise; - function attempt(f: (a: A) => T, a: A): Promise; + interface LiftedFn0 extends Fn0> { } + interface LiftedFn1 extends Fn1, Promise> { } + interface LiftedFn2 extends Fn2, A2 | Promise, Promise> { } + interface LiftedFn3 extends Fn3, A2 | Promise, A3 | Promise, Promise> { } + interface LiftedFn4 extends Fn4, A2 | Promise, A3 | Promise, A4 | Promise, Promise> { } + interface LiftedFn5 extends Fn5, A2 | Promise, A3 | Promise, A4 | Promise, A5 | Promise, Promise> { } - function attempt(f: (a: A, b: B) => T, a: Promise, b: Promise): Promise; - function attempt(f: (a: A, b: B) => T, a: Promise, b: B): Promise; - function attempt(f: (a: A, b: B) => T, a: A, b: Promise): Promise; - function attempt(f: (a: A, b: B) => T, a: A, b: B): Promise; + interface NodeCallback { (err: any, result: T): void } - function attempt(f: (a: A, b: B, c: C) => T, a: Promise, b: Promise, c: Promise): Promise; - function attempt(f: (a: A, b: B, c: C) => T, a: Promise, b: Promise, c: C): Promise; - function attempt(f: (a: A, b: B, c: C) => T, a: Promise, b: B, c: Promise): Promise; - function attempt(f: (a: A, b: B, c: C) => T, a: Promise, b: B, c: C): Promise; - function attempt(f: (a: A, b: B, c: C) => T, a: A, b: Promise, c: Promise): Promise; - function attempt(f: (a: A, b: B, c: C) => T, a: A, b: Promise, c: C): Promise; - function attempt(f: (a: A, b: B, c: C) => T, a: A, b: B, c: Promise): Promise; - function attempt(f: (a: A, b: B, c: C) => T, a: A, b: B, c: C): Promise; + interface NodeFn0 extends _.Fn1, void> { } + interface NodeFn1 extends _.Fn2, void> { } + interface NodeFn2 extends _.Fn3, void> { } + interface NodeFn3 extends _.Fn4, void> { } + interface NodeFn4 extends _.Fn5, void> { } + interface NodeFn5 extends _.Fn6, void> { } + } - function lift(f: () => T): () => Promise; - function lift(f: (a: A) => T): (a: Promise) => Promise; - function lift(f: (a: A, b: B) => T): (a: Promise, b: Promise) => Promise; - function lift(f: (a: A, b: B, c: C) => T): (a: Promise, b: Promise, c: Promise) => Promise; + function attempt( + f: _.Fn0 + ): Promise; + + function attempt( + f: _.Fn1, + arg1: A1 | Promise + ): Promise; + + function attempt( + f: _.Fn2, + arg1: A1 | Promise, + arg2: A2 | Promise + ): Promise; + + function attempt( + f: _.Fn3, + arg1: A1 | Promise, + arg2: A2 | Promise, + arg3: A3 | Promise + ): Promise; + + function attempt( + f: _.Fn4, + arg1: A1 | Promise, + arg2: A2 | Promise, + arg3: A3 | Promise, + arg4: A4 | Promise + ): Promise; + + function attempt( + f: _.Fn5, + arg1: A1 | Promise, + arg2: A2 | Promise, + arg3: A3 | Promise, + arg4: A4 | Promise, + arg5: A5 | Promise + ): Promise; + + + function lift(f: _.Fn0): _.LiftedFn0; + function lift(f: _.Fn1): _.LiftedFn1; + function lift(f: _.Fn2): _.LiftedFn2; + function lift(f: _.Fn3): _.LiftedFn3; + function lift(f: _.Fn4): _.LiftedFn4; + function lift(f: _.Fn5): _.LiftedFn5; function promise(resolver: (resolve: (value: T) => void, reject: (reason: any) => void) => void): Promise; @@ -92,16 +142,13 @@ declare module When { } interface Promise { - catch(onRejected?: (reason: any) => Promise): Promise; - catch(onRejected?: (reason: any) => U): Promise; + catch(onRejected?: (reason: any) => U | Promise): Promise; - catch(filter: (reason: any) => boolean, onRejected?: (reason: any) => Promise): Promise; - catch(filter: (reason: any) => boolean, onRejected?: (reason: any) => U): Promise; + catch(filter: (reason: any) => boolean, onRejected?: (reason: any) => U | Promise): Promise; // Make sure you test any usage of these overloads, exceptionType must // be a constructor with prototype set to an instance of Error. catch(exceptionType: any, onRejected?: (reason: any) => Promise): Promise; - catch(exceptionType: any, onRejected?: (reason: any) => U): Promise; finally(onFulfilledOrRejected: Function): Promise; @@ -109,8 +156,7 @@ declare module When { inspect(): Snapshot; - yield(value: Promise): Promise; - yield(value: U): Promise; + yield(value: U | Promise): Promise; else(value: T): Promise; orElse(value: T): Promise; @@ -124,29 +170,19 @@ declare module When { with(thisArg: any): Promise; withThis(thisArg: any): Promise; - otherwise(onRejected?: (reason: any) => Promise): Promise; - otherwise(onRejected?: (reason: any) => U): Promise; + otherwise(onRejected?: (reason: any) => U | Promise): Promise; - otherwise(predicate: (reason: any) => boolean, onRejected?: (reason: any) => Promise): Promise; - otherwise(predicate: (reason: any) => boolean, onRejected?: (reason: any) => U): Promise; + otherwise(predicate: (reason: any) => boolean, onRejected?: (reason: any) => U | Promise): Promise; // Make sure you test any usage of these overloads, exceptionType must // be a constructor with prototype set to an instance of Error. - otherwise(exceptionType: any, onRejected?: (reason: any) => Promise): Promise; - otherwise(exceptionType: any, onRejected?: (reason: any) => U): Promise; + otherwise(exceptionType: any, onRejected?: (reason: any) => U | Promise): Promise; - then(onFulfilled: (value: T) => Promise, onRejected?: (reason: any) => Promise, onProgress?: (update: any) => void): Promise; - then(onFulfilled: (value: T) => Promise, onRejected?: (reason: any) => U, onProgress?: (update: any) => void): Promise; - then(onFulfilled: (value: T) => U, onRejected?: (reason: any) => Promise, onProgress?: (update: any) => void): Promise; - then(onFulfilled: (value: T) => U, onRejected?: (reason: any) => U, onProgress?: (update: any) => void): Promise; + then(onFulfilled: (value: T) => U | Promise, onRejected?: (reason: any) => U | Promise, onProgress?: (update: any) => void): Promise; done(onFulfilled: (value: T) => void, onRejected?: (reason: any) => void): void; - fold(combine: (value1: T, value2: V) => Promise, value2: V): Promise; - fold(combine: (value1: T, value2: V) => Promise, value2: Promise): Promise; - - fold(combine: (value1: T, value2: V) => U, value2: V): Promise; - fold(combine: (value1: T, value2: V) => U, value2: Promise): Promise; + fold(combine: (value1: T, value2: V) => U | Promise, value2: V | Promise): Promise; } interface Thenable { @@ -166,42 +202,67 @@ declare module "when" { declare module "when/node" { import when = require('when'); + import _ = when._; - function lift(fn: (callback: (err: any, result: TResult) => void) => void): () => when.Promise; - function lift(fn: (arg1: TArg1, callback: (err: any, result: TResult) => void) => void): (arg1: when.Promise) => when.Promise; - function lift(fn: (arg1: TArg1, arg2: TArg2, callback: (err: any, result: TResult) => void) => void): (arg1: when.Promise, arg2: when.Promise) => when.Promise; - function lift(fn: (arg1: TArg1, arg2: TArg2, arg3: TArg3, callback: (err: any, result: TResult) => void) => void): (arg1: when.Promise, arg2: when.Promise, arg3: when.Promise) => when.Promise; + function lift(fn: _.NodeFn0): _.LiftedFn0; + function lift(fn: _.NodeFn1): _.LiftedFn1; + function lift(fn: _.NodeFn2): _.LiftedFn2; + function lift(fn: _.NodeFn3): _.LiftedFn3; + function lift(fn: _.NodeFn4): _.LiftedFn4; + function lift(fn: _.NodeFn5): _.LiftedFn5; + + + function call( + fn: _.NodeFn0 + ): when.Promise; + + function call( + fn: _.NodeFn1, + arg1: A1 | when.Promise + ): when.Promise; + + function call( + fn: _.NodeFn2, + arg1: A1 | when.Promise, + arg2: A2 | when.Promise + ): when.Promise; + + function call( + fn: _.NodeFn3, + arg1: A1 | when.Promise, + arg2: A2 | when.Promise, + arg3: A3 | when.Promise + ): when.Promise; + + function call( + fn: _.NodeFn4, + arg1: A1 | when.Promise, + arg2: A2 | when.Promise, + arg3: A3 | when.Promise, + arg4: A4 | when.Promise + ): when.Promise; + + function call( + fn: _.NodeFn5, + arg1: A1 | when.Promise, + arg2: A2 | when.Promise, + arg3: A3 | when.Promise, + arg4: A4 | when.Promise, + arg5: A5 | when.Promise + ): when.Promise; + + + function apply(fn: _.NodeFn0, args: any[]): when.Promise; + function apply(fn: _.NodeFn1, args: any[]): when.Promise; + function apply(fn: _.NodeFn2, args: any[]): when.Promise; + function apply(fn: _.NodeFn3, args: any[]): when.Promise; + function apply(fn: _.NodeFn4, args: any[]): when.Promise; + function apply(fn: _.NodeFn5, args: any[]): when.Promise; function liftAll(srcApi: any, transform?: (destApi: any, liftedFunc: Function, name: string) => any, destApi?: any): any; - function call(fn: (callback: (err: any, result: TResult) => void) => void): when.Promise; - - function call(fn: (arg1: TArg1, callback: (err: any, result: TResult) => void) => void, arg1: TArg1): when.Promise; - function call(fn: (arg1: TArg1, callback: (err: any, result: TResult) => void) => void, arg1: when.Promise): when.Promise; - - function call(fn: (arg1: TArg1, arg2: TArg2, callback: (err: any, result: TResult) => void) => void, arg1: TArg1, arg2: TArg2): when.Promise; - function call(fn: (arg1: TArg1, arg2: TArg2, callback: (err: any, result: TResult) => void) => void, arg1: when.Promise, arg2: TArg2): when.Promise; - function call(fn: (arg1: TArg1, arg2: TArg2, callback: (err: any, result: TResult) => void) => void, arg1: TArg1, arg2: when.Promise): when.Promise; - function call(fn: (arg1: TArg1, arg2: TArg2, callback: (err: any, result: TResult) => void) => void, arg1: when.Promise, arg2: when.Promise): when.Promise; - - function call(fn: (arg1: TArg1, arg2: TArg2, arg3: TArg3, callback: (err: any, result: TResult) => void) => void, arg1: TArg1, arg2: TArg2, arg3: TArg3): when.Promise; - function call(fn: (arg1: TArg1, arg2: TArg2, arg3: TArg3, callback: (err: any, result: TResult) => void) => void, arg1: TArg1, arg2: TArg2, arg3: when.Promise): when.Promise; - function call(fn: (arg1: TArg1, arg2: TArg2, arg3: TArg3, callback: (err: any, result: TResult) => void) => void, arg1: TArg1, arg2: when.Promise, arg3: TArg3): when.Promise; - function call(fn: (arg1: TArg1, arg2: TArg2, arg3: TArg3, callback: (err: any, result: TResult) => void) => void, arg1: TArg1, arg2: when.Promise, arg3: when.Promise): when.Promise; - function call(fn: (arg1: TArg1, arg2: TArg2, arg3: TArg3, callback: (err: any, result: TResult) => void) => void, arg1: when.Promise, arg2: TArg2, arg3: TArg3): when.Promise; - function call(fn: (arg1: TArg1, arg2: TArg2, arg3: TArg3, callback: (err: any, result: TResult) => void) => void, arg1: when.Promise, arg2: TArg2, arg3: when.Promise): when.Promise; - function call(fn: (arg1: TArg1, arg2: TArg2, arg3: TArg3, callback: (err: any, result: TResult) => void) => void, arg1: when.Promise, arg2: when.Promise, arg3: TArg3): when.Promise; - function call(fn: (arg1: TArg1, arg2: TArg2, arg3: TArg3, callback: (err: any, result: TResult) => void) => void, arg1: when.Promise, arg2: when.Promise, arg3: when.Promise): when.Promise; - - - function apply(fn: (callback: (err: any, result: TResult) => void) => void, args: any[]): when.Promise; - function apply(fn: (arg1: any, callback: (err: any, result: TResult) => void) => void, args: any[]): when.Promise; - function apply(fn: (arg1: any, arg2: any, callback: (err: any, result: TResult) => void) => void, args: any[]): when.Promise; - function apply(fn: (arg1: any, arg2: any, arg3: any, callback: (err: any, result: TResult) => void) => void, args: any[]): when.Promise; - - function liftCallback(callback: (err: any, arg: TArg) => void): (value: when.Promise) => when.Promise;