From c54c8658e188c764fa0c20a8beb5a310a3296e73 Mon Sep 17 00:00:00 2001 From: onichandame Date: Thu, 11 Jun 2020 06:00:45 +0000 Subject: [PATCH 1/9] added recursive --- index.d.ts | 1 + source/promise-value-recursive.d.ts | 22 ++++++++++++++++++++++ test-d/promise-value-recursive.ts | 18 ++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 source/promise-value-recursive.d.ts create mode 100644 test-d/promise-value-recursive.ts diff --git a/index.d.ts b/index.d.ts index c0fc61cd2..adc9458e9 100644 --- a/index.d.ts +++ b/index.d.ts @@ -17,6 +17,7 @@ export {SetOptional} from './source/set-optional'; export {SetRequired} from './source/set-required'; export {ValueOf} from './source/value-of'; export {PromiseValue} from './source/promise-value'; +export {PromiseValueRecursive} from './source/promise-value-recursive'; export {AsyncReturnType} from './source/async-return-type'; export {ConditionalExcept} from './source/conditional-except'; export {ConditionalKeys} from './source/conditional-keys'; diff --git a/source/promise-value-recursive.d.ts b/source/promise-value-recursive.d.ts new file mode 100644 index 000000000..21ceeb693 --- /dev/null +++ b/source/promise-value-recursive.d.ts @@ -0,0 +1,22 @@ +/** +Returns the type that is wrapped inside a `Promise` type. +If the type is not a `Promise`, the type itself is returned. + +@example +``` +import {PromiseValue} from 'type-fest'; + +type AsyncData = Promise; +let asyncData: PromiseValue = Promise.resolve('ABC'); + +type Data = PromiseValue; +let data: Data = await asyncData; + +// Here's an example that shows how this type reacts to non-Promise types. +type SyncData = PromiseValue; +let syncData: SyncData = getSyncData(); +``` +*/ +export type PromiseValueRecursive = PromiseType extends Promise + ? {0: PromiseValueRecursive; 1: Value}[PromiseType extends Promise? 0 : 1] + : Otherwise; diff --git a/test-d/promise-value-recursive.ts b/test-d/promise-value-recursive.ts new file mode 100644 index 000000000..d22e94bb9 --- /dev/null +++ b/test-d/promise-value-recursive.ts @@ -0,0 +1,18 @@ +import {expectAssignable} from 'tsd'; +import {PromiseValueRecursive} from '..'; + +type NumberPromise = Promise; +type NestedPromise = Promise; +type Otherwise = object; + +// Test the nested behaviour. +expectAssignable>(2); + +// Test the unnested behaviour. +expectAssignable>(2); + +// Test what happens when the `PromiseValue` type is not handed a `Promise` type. +expectAssignable>(2); + +// Test the `Otherwise` generic parameter. +expectAssignable>({}); From b3550b614a56ee07e44a97b20ef52ddfec21798c Mon Sep 17 00:00:00 2001 From: onichandame Date: Thu, 11 Jun 2020 06:12:22 +0000 Subject: [PATCH 2/9] example --- source/promise-value-recursive.d.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/source/promise-value-recursive.d.ts b/source/promise-value-recursive.d.ts index 21ceeb693..109062491 100644 --- a/source/promise-value-recursive.d.ts +++ b/source/promise-value-recursive.d.ts @@ -1,19 +1,25 @@ /** Returns the type that is wrapped inside a `Promise` type. -If the type is not a `Promise`, the type itself is returned. +If the type is not a Promise, the type itself is returned. +If the type wrapped in the Promise is itself a Promise, the resolved type will be unwrapped recursively. +If the Promise is guaranteed not to be recursive, use `PromiseValue` instead. @example ``` -import {PromiseValue} from 'type-fest'; +import {PromiseValueRecursive} from 'type-fest'; -type AsyncData = Promise; -let asyncData: PromiseValue = Promise.resolve('ABC'); +type RecursiveAsyncData = Promise >; +let recursiveAsyncData: PromiseValueRecursive = Promise.resolve(Promise.resolve('ABC')); -type Data = PromiseValue; +type Data = PromiseValue; let data: Data = await asyncData; +// Here's an example that shows how this type reacts to non-recursive Promise types. +type AsyncData = PromiseValueRecursive >; +let asyncData: AsyncData = await getAsyncData(); + // Here's an example that shows how this type reacts to non-Promise types. -type SyncData = PromiseValue; +type SyncData = PromiseValueRecursive; let syncData: SyncData = getSyncData(); ``` */ From ddaf1c97962db12369fa48c8ce8e4c6408005621 Mon Sep 17 00:00:00 2001 From: onichandame Date: Thu, 11 Jun 2020 06:14:26 +0000 Subject: [PATCH 3/9] readme --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index 15046af94..4f9169f46 100644 --- a/readme.md +++ b/readme.md @@ -76,6 +76,7 @@ Click the type names for complete docs. - [`SetRequired`](source/set-required.d.ts) - Create a type that makes the given keys required. - [`ValueOf`](source/value-of.d.ts) - Create a union of the given object's values, and optionally specify which keys to get the values from. - [`PromiseValue`](source/promise-value.d.ts) - Returns the type that is wrapped inside a `Promise`. +- [`PromiseValueRecursive`](source/promise-value-recursive.d.ts) - Returns the type that is wrapped inside a `Promise` recursively. - [`AsyncReturnType`](source/async-return-type.d.ts) - Unwrap the return type of a function that returns a `Promise`. - [`ConditionalKeys`](source/conditional-keys.d.ts) - Extract keys from a shape where values extend the given `Condition` type. - [`ConditionalPick`](source/conditional-pick.d.ts) - Like `Pick` except it selects properties from a shape where the values extend the given `Condition` type. From 5b5b20b721e298d314288a1f0d57f1e1a01cfa0f Mon Sep 17 00:00:00 2001 From: onichandame Date: Thu, 11 Jun 2020 07:44:00 +0000 Subject: [PATCH 4/9] merged changes to PromiseValue --- index.d.ts | 1 - readme.md | 1 - source/promise-value-recursive.d.ts | 28 ---------------------------- source/promise-value.d.ts | 8 +++++++- test-d/promise-value-recursive.ts | 18 ------------------ test-d/promise-value.ts | 4 ++++ 6 files changed, 11 insertions(+), 49 deletions(-) delete mode 100644 source/promise-value-recursive.d.ts delete mode 100644 test-d/promise-value-recursive.ts diff --git a/index.d.ts b/index.d.ts index adc9458e9..c0fc61cd2 100644 --- a/index.d.ts +++ b/index.d.ts @@ -17,7 +17,6 @@ export {SetOptional} from './source/set-optional'; export {SetRequired} from './source/set-required'; export {ValueOf} from './source/value-of'; export {PromiseValue} from './source/promise-value'; -export {PromiseValueRecursive} from './source/promise-value-recursive'; export {AsyncReturnType} from './source/async-return-type'; export {ConditionalExcept} from './source/conditional-except'; export {ConditionalKeys} from './source/conditional-keys'; diff --git a/readme.md b/readme.md index 4f9169f46..15046af94 100644 --- a/readme.md +++ b/readme.md @@ -76,7 +76,6 @@ Click the type names for complete docs. - [`SetRequired`](source/set-required.d.ts) - Create a type that makes the given keys required. - [`ValueOf`](source/value-of.d.ts) - Create a union of the given object's values, and optionally specify which keys to get the values from. - [`PromiseValue`](source/promise-value.d.ts) - Returns the type that is wrapped inside a `Promise`. -- [`PromiseValueRecursive`](source/promise-value-recursive.d.ts) - Returns the type that is wrapped inside a `Promise` recursively. - [`AsyncReturnType`](source/async-return-type.d.ts) - Unwrap the return type of a function that returns a `Promise`. - [`ConditionalKeys`](source/conditional-keys.d.ts) - Extract keys from a shape where values extend the given `Condition` type. - [`ConditionalPick`](source/conditional-pick.d.ts) - Like `Pick` except it selects properties from a shape where the values extend the given `Condition` type. diff --git a/source/promise-value-recursive.d.ts b/source/promise-value-recursive.d.ts deleted file mode 100644 index 109062491..000000000 --- a/source/promise-value-recursive.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** -Returns the type that is wrapped inside a `Promise` type. -If the type is not a Promise, the type itself is returned. -If the type wrapped in the Promise is itself a Promise, the resolved type will be unwrapped recursively. -If the Promise is guaranteed not to be recursive, use `PromiseValue` instead. - -@example -``` -import {PromiseValueRecursive} from 'type-fest'; - -type RecursiveAsyncData = Promise >; -let recursiveAsyncData: PromiseValueRecursive = Promise.resolve(Promise.resolve('ABC')); - -type Data = PromiseValue; -let data: Data = await asyncData; - -// Here's an example that shows how this type reacts to non-recursive Promise types. -type AsyncData = PromiseValueRecursive >; -let asyncData: AsyncData = await getAsyncData(); - -// Here's an example that shows how this type reacts to non-Promise types. -type SyncData = PromiseValueRecursive; -let syncData: SyncData = getSyncData(); -``` -*/ -export type PromiseValueRecursive = PromiseType extends Promise - ? {0: PromiseValueRecursive; 1: Value}[PromiseType extends Promise? 0 : 1] - : Otherwise; diff --git a/source/promise-value.d.ts b/source/promise-value.d.ts index 7686dd11d..4f28da3cb 100644 --- a/source/promise-value.d.ts +++ b/source/promise-value.d.ts @@ -15,6 +15,12 @@ let data: Data = await asyncData; // Here's an example that shows how this type reacts to non-Promise types. type SyncData = PromiseValue; let syncData: SyncData = getSyncData(); + +// Here's an example that shows how this type reacts to recursive Promise types. +type RecursiveAsyncData = Promise >; +let recursiveAsyncData: PromiseValue = Promise.resolve(Promise.resolve('ABC')); ``` */ -export type PromiseValue = PromiseType extends Promise ? Value : Otherwise; +export type PromiseValue = PromiseType extends Promise + ? {0: PromiseValue; 1: Value}[PromiseType extends Promise? 0 : 1] + : Otherwise; diff --git a/test-d/promise-value-recursive.ts b/test-d/promise-value-recursive.ts deleted file mode 100644 index d22e94bb9..000000000 --- a/test-d/promise-value-recursive.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {expectAssignable} from 'tsd'; -import {PromiseValueRecursive} from '..'; - -type NumberPromise = Promise; -type NestedPromise = Promise; -type Otherwise = object; - -// Test the nested behaviour. -expectAssignable>(2); - -// Test the unnested behaviour. -expectAssignable>(2); - -// Test what happens when the `PromiseValue` type is not handed a `Promise` type. -expectAssignable>(2); - -// Test the `Otherwise` generic parameter. -expectAssignable>({}); diff --git a/test-d/promise-value.ts b/test-d/promise-value.ts index 7a91156e6..76f866c48 100644 --- a/test-d/promise-value.ts +++ b/test-d/promise-value.ts @@ -2,11 +2,15 @@ import {expectAssignable} from 'tsd'; import {PromiseValue} from '..'; type NumberPromise = Promise; +type NestedPromise = Promise; type Otherwise = object; // Test the normal behaviour. expectAssignable>(2); +// Test the nested behaviour. +expectAssignable>(2); + // Test what happens when the `PromiseValue` type is not handed a `Promise` type. expectAssignable>(2); From cd2ae75947f0674261b28aa2ea0d20f1e63d8985 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sat, 13 Jun 2020 16:10:24 +0800 Subject: [PATCH 5/9] Update promise-value.d.ts --- source/promise-value.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/promise-value.d.ts b/source/promise-value.d.ts index 4f28da3cb..e360652eb 100644 --- a/source/promise-value.d.ts +++ b/source/promise-value.d.ts @@ -22,5 +22,5 @@ let recursiveAsyncData: PromiseValue = Promise.resolve(Promi ``` */ export type PromiseValue = PromiseType extends Promise - ? {0: PromiseValue; 1: Value}[PromiseType extends Promise? 0 : 1] - : Otherwise; + ? {0: PromiseValue; 1: Value}[PromiseType extends Promise ? 0 : 1] + : Otherwise; From 8e79a91bf8870cdb01f8a04663e2e3834b75e433 Mon Sep 17 00:00:00 2001 From: onichandame Date: Sat, 13 Jun 2020 17:01:55 +0000 Subject: [PATCH 6/9] added description --- source/promise-value.d.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/source/promise-value.d.ts b/source/promise-value.d.ts index e360652eb..236190c71 100644 --- a/source/promise-value.d.ts +++ b/source/promise-value.d.ts @@ -1,5 +1,6 @@ /** Returns the type that is wrapped inside a `Promise` type. +If the type is a nested Promise, it is unwrapped recursively until a non-Promise type is obtained. If the type is not a `Promise`, the type itself is returned. @example @@ -21,6 +22,11 @@ type RecursiveAsyncData = Promise >; let recursiveAsyncData: PromiseValue = Promise.resolve(Promise.resolve('ABC')); ``` */ -export type PromiseValue = PromiseType extends Promise - ? {0: PromiseValue; 1: Value}[PromiseType extends Promise ? 0 : 1] +export type PromiseValue< + PromiseType, + Otherwise = PromiseType +> = PromiseType extends Promise + ? { 0: PromiseValue; 1: Value }[PromiseType extends Promise + ? 0 + : 1] : Otherwise; From 29626a5a282a6d251659314575aed7d3cfda2653 Mon Sep 17 00:00:00 2001 From: onichandame Date: Sat, 13 Jun 2020 17:04:51 +0000 Subject: [PATCH 7/9] lint --- source/promise-value.d.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/source/promise-value.d.ts b/source/promise-value.d.ts index 236190c71..5e57fb66e 100644 --- a/source/promise-value.d.ts +++ b/source/promise-value.d.ts @@ -22,11 +22,6 @@ type RecursiveAsyncData = Promise >; let recursiveAsyncData: PromiseValue = Promise.resolve(Promise.resolve('ABC')); ``` */ -export type PromiseValue< - PromiseType, - Otherwise = PromiseType -> = PromiseType extends Promise - ? { 0: PromiseValue; 1: Value }[PromiseType extends Promise - ? 0 - : 1] +export type PromiseValue = PromiseType extends Promise + ? { 0: PromiseValue; 1: Value }[PromiseType extends Promise ? 0 : 1] : Otherwise; From 8eb880364f07611474c25355e855ea09d49d4d79 Mon Sep 17 00:00:00 2001 From: onichandame Date: Sat, 13 Jun 2020 17:07:24 +0000 Subject: [PATCH 8/9] unknown instead of any --- source/promise-value.d.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source/promise-value.d.ts b/source/promise-value.d.ts index 5e57fb66e..c3d558317 100644 --- a/source/promise-value.d.ts +++ b/source/promise-value.d.ts @@ -22,6 +22,11 @@ type RecursiveAsyncData = Promise >; let recursiveAsyncData: PromiseValue = Promise.resolve(Promise.resolve('ABC')); ``` */ -export type PromiseValue = PromiseType extends Promise - ? { 0: PromiseValue; 1: Value }[PromiseType extends Promise ? 0 : 1] +export type PromiseValue< + PromiseType, + Otherwise = PromiseType +> = PromiseType extends Promise + ? { 0: PromiseValue; 1: Value }[PromiseType extends Promise + ? 0 + : 1] : Otherwise; From 10859d6e0a38afbb62cb01dd9d33d22c716208ed Mon Sep 17 00:00:00 2001 From: onichandame Date: Sat, 13 Jun 2020 17:10:00 +0000 Subject: [PATCH 9/9] lint --- source/promise-value.d.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/source/promise-value.d.ts b/source/promise-value.d.ts index c3d558317..642ddebcc 100644 --- a/source/promise-value.d.ts +++ b/source/promise-value.d.ts @@ -22,11 +22,6 @@ type RecursiveAsyncData = Promise >; let recursiveAsyncData: PromiseValue = Promise.resolve(Promise.resolve('ABC')); ``` */ -export type PromiseValue< - PromiseType, - Otherwise = PromiseType -> = PromiseType extends Promise - ? { 0: PromiseValue; 1: Value }[PromiseType extends Promise - ? 0 - : 1] +export type PromiseValue = PromiseType extends Promise + ? { 0: PromiseValue; 1: Value }[PromiseType extends Promise ? 0 : 1] : Otherwise;