From a9a4b4d84970df5d102b18ddf97ffd73a46a7040 Mon Sep 17 00:00:00 2001 From: Josh Rosenstein <32781407+JoshRosenstein@users.noreply.github.com> Date: Sun, 14 Apr 2019 21:17:58 -0400 Subject: [PATCH 1/7] feat: add UnionToIntersection --- src/types/utils.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/types/utils.ts b/src/types/utils.ts index b4e9244..a7b6db6 100644 --- a/src/types/utils.ts +++ b/src/types/utils.ts @@ -34,3 +34,13 @@ export type Nominal = T & Tagged; * @returns a the type union with a promise containing the given type */ export type PromiseOr = Promise | T; + + +/** + * Defines an intersection type of all union items. + * @param U Union of any types that will be intersected. + * @returns U items intersected + * @see https://stackoverflow.com/a/50375286/9259330 + */ +export type UnionToIntersection = + (U extends unknown ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never; From a756c7bc7f6d04f71e76e6b020167e67cc8076b0 Mon Sep 17 00:00:00 2001 From: Josh Rosenstein <32781407+JoshRosenstein@users.noreply.github.com> Date: Sun, 14 Apr 2019 21:21:02 -0400 Subject: [PATCH 2/7] test: add UnionToIntersection --- test/utils/UnionToIntersection.test.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 test/utils/UnionToIntersection.test.ts diff --git a/test/utils/UnionToIntersection.test.ts b/test/utils/UnionToIntersection.test.ts new file mode 100644 index 0000000..d17ec02 --- /dev/null +++ b/test/utils/UnionToIntersection.test.ts @@ -0,0 +1,25 @@ +import test from 'ava'; +import { assert } from '../helpers/assert'; + +import { UnionToIntersection} from '../../src'; + +test('Union of Strings', t => { + type got = UnionToIntersection<'hi' | 'there'>; + type expected = 'hi' & 'there'; + + assert(t); +}); + +test('Union of Objects', t => { + type got = UnionToIntersection< { a: 0 } | + { b: 1 } | + { c: 2 }>; + + type expected = { + a: 0 + b: 1 + c: 2 + }; + + assert(t); +}); From 2e3ae207c2b367cdadcfbf4178d372917bdbffc3 Mon Sep 17 00:00:00 2001 From: Josh Rosenstein <32781407+JoshRosenstein@users.noreply.github.com> Date: Sun, 14 Apr 2019 21:23:43 -0400 Subject: [PATCH 3/7] feat: improve IntersectTuple --- src/types/tuples.ts | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/types/tuples.ts b/src/types/tuples.ts index 7783a66..f25e80d 100644 --- a/src/types/tuples.ts +++ b/src/types/tuples.ts @@ -1,3 +1,5 @@ +import {UnionToIntersection} from './utils'; + export interface Vector { readonly [x: number]: T; readonly length: number; } export type Length> = T['length']; @@ -12,15 +14,4 @@ export type UnionizeTuple> = T[number]; * @param T a tuple of items up to 10 * @returns an intersection of all items in the tuple */ -export type IntersectTuple> = - Length extends 1 ? T[0] : - Length extends 2 ? T[0] & T[1] : - Length extends 3 ? T[0] & T[1] & T[2] : - Length extends 4 ? T[0] & T[1] & T[2] & T[3] : - Length extends 5 ? T[0] & T[1] & T[2] & T[3] & T[4] : - Length extends 6 ? T[0] & T[1] & T[2] & T[3] & T[4] & T[5] : - Length extends 7 ? T[0] & T[1] & T[2] & T[3] & T[4] & T[5] & T[6] : - Length extends 8 ? T[0] & T[1] & T[2] & T[3] & T[4] & T[5] & T[6] & T[7] : - Length extends 9 ? T[0] & T[1] & T[2] & T[3] & T[4] & T[5] & T[6] & T[7] & T[8] : - Length extends 10 ? T[0] & T[1] & T[2] & T[3] & T[4] & T[5] & T[6] & T[7] & T[8] & T[9] : - any; +export type IntersectTuple>= UnionToIntersection; From 1449b8c29bbbbce7e77cde6f23fbce34f848bdc3 Mon Sep 17 00:00:00 2001 From: andy Date: Sun, 21 Apr 2019 14:12:49 -0600 Subject: [PATCH 4/7] docs: remove condition on tuple length --- src/types/tuples.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/tuples.ts b/src/types/tuples.ts index f25e80d..43b33f0 100644 --- a/src/types/tuples.ts +++ b/src/types/tuples.ts @@ -11,7 +11,7 @@ export type Length> = T['length']; export type UnionizeTuple> = T[number]; /** * Gives an intersection of all values contained in a tuple. - * @param T a tuple of items up to 10 + * @param T a tuple of items * @returns an intersection of all items in the tuple */ export type IntersectTuple>= UnionToIntersection; From 3b1da10394bc7d14bc42d015c261f109d50e938b Mon Sep 17 00:00:00 2001 From: andy Date: Sun, 21 Apr 2019 14:13:09 -0600 Subject: [PATCH 5/7] docs: generate documentation --- README.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0338004..5376305 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ npm install --save-dev simplytyped **[Utils](#utils)** -[NoInfer](#noinfer) - [Nominal](#nominal) - [Nullable](#nullable) - [PromiseOr](#promiseor) +[NoInfer](#noinfer) - [Nominal](#nominal) - [Nullable](#nullable) - [PromiseOr](#promiseor) - [UnionToIntersection](#uniontointersection) **[Functions](#functions)** @@ -581,6 +581,32 @@ test('Will give back a promise containing given type union the type itself', t = ``` +### UnionToIntersection +Defines an intersection type of all union items. +```ts +test('Union of Strings', t => { + type got = UnionToIntersection<'hi' | 'there'>; + type expected = 'hi' & 'there'; + + assert(t); +}); + +test('Union of Objects', t => { + type got = UnionToIntersection< { a: 0 } | + { b: 1 } | + { c: 2 }>; + + type expected = { + a: 0 + b: 1 + c: 2 + }; + + assert(t); +}); + +``` + ## Functions ### AnyFunc From 76150c18850aa41f6309218c7206b3d5d0e4fd9d Mon Sep 17 00:00:00 2001 From: andy Date: Sun, 21 Apr 2019 14:21:30 -0600 Subject: [PATCH 6/7] test: make styles more uniform --- test/utils/UnionToIntersection.test.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/test/utils/UnionToIntersection.test.ts b/test/utils/UnionToIntersection.test.ts index d17ec02..03e645e 100644 --- a/test/utils/UnionToIntersection.test.ts +++ b/test/utils/UnionToIntersection.test.ts @@ -11,15 +11,13 @@ test('Union of Strings', t => { }); test('Union of Objects', t => { - type got = UnionToIntersection< { a: 0 } | - { b: 1 } | - { c: 2 }>; + type got = UnionToIntersection<{ a: 0 } | { b: 1 } | { c: 2 }>; - type expected = { - a: 0 - b: 1 - c: 2 - }; + type expected = { + a: 0, + b: 1, + c: 2, + }; assert(t); }); From 42cc8c3e78951970ec72c6d7c29b7a429bfdf87e Mon Sep 17 00:00:00 2001 From: andy Date: Sun, 21 Apr 2019 14:21:53 -0600 Subject: [PATCH 7/7] docs: generate documentation --- README.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 5376305..51e1806 100644 --- a/README.md +++ b/README.md @@ -592,15 +592,13 @@ test('Union of Strings', t => { }); test('Union of Objects', t => { - type got = UnionToIntersection< { a: 0 } | - { b: 1 } | - { c: 2 }>; - - type expected = { - a: 0 - b: 1 - c: 2 - }; + type got = UnionToIntersection<{ a: 0 } | { b: 1 } | { c: 2 }>; + + type expected = { + a: 0, + b: 1, + c: 2, + }; assert(t); });