It seems like you are interested in creating a type called AllEvents
based on certain criteria programmatically:
type AllEvents = {
name: "foo" | "bar";
value: "baz";
}
This type would allow you to easily access the union types within it using keys like "name"
and "value"
.
To achieve this, we can start with a union type T
of object types (expected to be Events[number]
, which is the union of elements from events
). We first identify all the keys in this union by distributing the keyof
operator over unions in T
:
type AllKeys<T> = T extends unknown ? keyof T : never;
Next, we combine these keys into a single object type. For each key K
in AllKeys<T>
, we filter the union T
to extract values associated with that key. This can be achieved using distributive conditional types and the infer
keyword for extraction:
type Combine<T> =
{ [K in AllKeys<T>]: T extends Record<K, infer V> ? V : never };
By combining these steps, we arrive at the final AllEvents
type as desired:
type AllEvents = Combine<Events[number]>;
/* type AllEvents = {
name: "foo" | "bar";
value: "baz";
} */
You can now access specific types within this structure by indexing as needed:
type Name = AllEvents['name'];
//type Name = "foo" | "bar"
Link to Playground with Code Example