Last active
October 1, 2021 10:15
-
-
Save gvergnaud/c84883cbba721fa2ede1c1117b6e5e80 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Helpers | |
type Expect<T extends true> = T | |
type Equal<X, Y> = | |
(<T>() => T extends X ? 1 : 2) extends | |
(<T>() => T extends Y ? 1 : 2) | |
? true | |
: false; | |
type Not<T extends boolean> = T extends true ? false : true; | |
/** | |
* Mapping over a union type. | |
* | |
* The trick is to use do | |
* ```ts | |
* type SomeGenericType<SomeUnion> = | |
* SomeUnion extends any | |
* ? {{ use SomeUnion here }} | |
* : never | |
* ``` | |
* | |
* `SomeUnion extends any` is of course always true, but that's not the point. | |
* The point is to execute the code contained in the first branch for each element of the `SomeUnion` union type. | |
* This is essentially a map. | |
* | |
* /!\ This only works inside of a Generic function! | |
*/ | |
type Strings = "a" | "b" | "c" | |
type Gen<T extends string> = | |
T extends any | |
? { key: T } | |
: never | |
type Gen2<T extends string> = | |
{ key: T } | |
type distributed = { key: "a" } | { key: "b" } | { key: "c" } | |
type nondistributed = { key: "a" | "b" | "c" } | |
type cases = [ | |
// this two types are NOT equal | |
Expect<Not<Equal<distributed, nondistributed>>>, | |
// The distribution works if it's inside a generic type and | |
// it uses T extends any to distribute all values. | |
Expect<Equal<Gen<Strings>, distributed>>, | |
// The distribution DOESN'T works if it's inside a generic type but | |
// it doesn't uses T extends any. | |
Expect<Equal<Gen2<Strings>, nondistributed>>, | |
// This doesn't work when it's inlined (which is a real problem imo, maybe even a bug) | |
Expect<Equal< | |
Strings extends infer T | |
? { key: T } | |
: never, | |
nondistributed | |
>>, | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment