Is it possible to create a type which contains all possible keys in the discriminated union (instead of just shared keys)?
If I have a discriminated union, such as:
type Form =
| { name?: string }
| { name?: string; query: string };
type Keys = keyof Form;
Currently Keys here resolves to "name", as that is the only shared key, however I'd like it to resolve to "name" | "query" (being the superset of all possible keys).
CodePudding user response:
You can use a distributive conditional type:
type UnionOfKeys<T> = T extends any ? keyof T : never;
type Keys = UnionOfKeys<Form>; // "name" | "query"
When conditional types act on a generic type, they become distributive when given a union type.
UnionOfKeys is a conditional type that acts on a generic type, so UnionOfKeys<T1 | T2> is equivalent to UnionOfKeys<T1> | UnionOfKeys<T2>, which simplifies to keyof T1 | keyof T2.
