Created
July 16, 2019 14:29
-
-
Save hasparus/cc61bff808843bc21d69c035fc0cf30c to your computer and use it in GitHub Desktop.
I'm sure it has no serious use case.
This file contains hidden or 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
namespace Products { | |
export type Car = { | |
name: 'Car'; | |
drive(): void; | |
} | |
export type IceCream = { | |
name: 'IceCream'; | |
flavor: string; | |
} | |
export interface Registry { | |
Car: Car; | |
IceCream: IceCream; | |
} | |
} | |
const carScream = { | |
names: ['Car', 'IceCream'] as const, | |
} | |
// #= Products.Car | Products.IceCream | |
type X1 = Products.Registry[typeof carScream.names[number]] | |
// #= Products.Car & Products.IceCream | |
type X2 = UnionToIntersection<Products.Registry[typeof carScream.names[number]]>; | |
type MergedProduct<Names extends keyof Products.Registry> = Omit< | |
UnionToIntersection<Products.Registry[typeof carScream.names[number]]>, | |
'name' | 'names' | |
> & { names: UnionToTuple<Names> } | |
const carScream2: MergedProduct<'Car' | 'IceCream'> = { | |
names: ['Car', 'IceCream'], | |
drive() { | |
console.log('Vroom'); | |
}, | |
flavor: 'pistachio' | |
} | |
// Utils | |
export type UnionToIntersection<Union> = | |
(Union extends any | |
? (argument: Union) => void | |
: never | |
) extends (argument: infer Intersection) => void | |
? Intersection | |
: never; | |
type Overwrite<T, S extends any> = { [P in keyof T]: S[P] }; | |
type TupleUnshift<T extends any[], X> = T extends any ? ((x: X, ...t: T) => void) extends (...t: infer R) => void ? R : never : never; | |
type TuplePush<T extends any[], X> = T extends any ? Overwrite<TupleUnshift<T, any>, T & { [x: string]: X }> : never; | |
type UnionToTuple<U> = UnionToTupleRecursively<[], U>; | |
type UnionToTupleRecursively<T extends any[], U> = { | |
1: T; | |
0: UnionToTupleRecursively_<T, U, U>; | |
}[[U] extends [never] ? 1 : 0] | |
type UnionToTupleRecursively_<T extends any[], U, S> = | |
S extends any ? UnionToTupleRecursively<TupleUnshift<T, S> | TuplePush<T, S>, Exclude<U, S>> : never; | |
let x: UnionToTuple<1 | 2 | 3 | 4> = [1, 2, 3, 4]; | |
let y: UnionToTuple<1 | 2 | 3 | 4> = [4, 3, 2, 1]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://typescript-play.js.org/#code/HYQwtgpgzgDiDGEAEAFATgewCYFd4BcokBvAKCQqQgA8YM18l8BPGZAYRDSQF4TzKg0JABcSAOSc04gNwDBFLGgCWANwgAKAJRjVGZVjmCAvqXlVa9RizZIAkonZoI4XvwWVhEMeIcQnLmCy5oIAZgA2IHpoYlD4KsAA5kaUpuY0dAxIysD4EGihCMgAShCJynFozO4eSFJiUikefgHgYi3O4DK15qZppPAYwHFI8FwAyvCdYG5kQuDQYgDaklziADQSHYHiALpIIESDw-jrpGkA9BdIAMR86Nh4hAB0UkgAPqiYuARQz9vgUg2ZAADQAjG4Hj8XqVypVmEtgRhQqMJlNAs8vFAlsAcGAAEb5Xa7MxXW73b5PP5vABkX0ev3+jmmQNYoIATG4AKrAZRDAAqGDsuXyUAgBD5wAAPFCqc9YRV4gikSixmhJtNMQtsbiCUTdgA+OSs2wAWXyiQgWFlBClADltRY8sAsEQANYQZjI+nQv4K+EGtwAeTAynwUvMPMlguFeTQYolQxllMZ-qViLZ3rVGoxWJxeMJaGJBrOgnEXnEHwkWPEpEDdOISCxYijAow-JwMHCEHt2sDaWOI2z6PA7LE5rQlutKfDq2kVd8zJ2gb4cyb2uWc42WyX4D2paQSjUmi0NUEg4w3ee4QwiQ04gAapgMEEtCljAeIlF6D4YIqEAAFnytaXNcXL4Mo4RQGYGRWEwbJIK2wAxiK8bihBSZISuAgaEhToQC6RAgMAzAhEgAD8SAaFwiR4gR+AtryQynjwgZ6AYZFiMAEDqGgAinjQzqulRNF0bkYg5KE+T2KhCYYcALFsfoWBkZRsaiuhkqcU2PH5MawJIEGvEAO4qHkUr8ps4z4YRBwkSuJBIEsKDZMASAel6KL8rsYjjM5+zGHIBkdl2EA8lAQGhOG-I2cJxEIrsmwgg5MWCQRcUkRRVEaNQYggpszyFQxSD8opSDsVgAnUEJRAaIVzzFZJ0nFGVFVZcUSBcbp3BdbxQUISF3YoDgEUWbFREkUsiVIMlbipdV6UTdUlFGfkplhj2g1hcMkXRZs8UliVSANk5uVIJUOSJD5M1IMYga9XpZgGUhgpbVKXIOS97adt2pTwDg8bHuEzBSlNmwffpCFfVtf0A1AQMg-NNV2Ql4MOWuFBgmI-JNEgAAMjHRt9oWw4D6jAwA+hZ4No3IxhLEsXL7Gltk4t1+yURCYh4ySJrINDP0QKT8Pk8wVNI4tKNg4hVnYYI1ksxly2IUxyHE794pwwjFmC+Fu3U0g4yBp8W3DaNlmG4dACi1DwOEOBYD2XKy-dOl9WY3aMGdAuhVKEKfJynwAMxVgALA5Sxgps7KbEHmyh7scie0gzCE22b3+0ggdICHnzh24Syh7H0ebGCiekEAA