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
.