0

This code allow me to send in props just one of the options but not the other, for example:

<Drawer volunteer />

now it's 3 properties, but if there is more how can i write it more generic ?

The Drawer types declaration:

type DrawerTypes =
    { volunteer: boolean } & { rescues?: never } & { map?: never } |
    { volunteer?: never } & { rescues: boolean } & { map?: never } |
    { volunteer?: never } & { rescues?: never } & { map: boolean };
Alex Wayne
  • 178,991
  • 47
  • 309
  • 337
  • Does [this previous answer about mutually-exclusive types](https://stackoverflow.com/a/53229567/21146235) help you? – motto Mar 20 '23 at 17:33

1 Answers1

0

You can use a mapped type to map over the keys, picking the specific key and making the others never:

type OneOf<T> = {
    [K in keyof T]: Pick<T, K> & Partial<Record<Exclude<keyof T, K>, never>>;
}[keyof T]

The new definition of DrawerTypes would be

type DrawerTypes = OneOf<{ volunteer: boolean; rescues: boolean; map: boolean }>;

Admittedly, the tooltip of DrawerTypes is not particularly helpful, so if you add this extra bit,

type OneOf<T> = {
    [K in keyof T]: Pick<T, K> & Partial<Record<Exclude<keyof T, K>, never>>;
}[keyof T] extends infer O ? { [K in keyof O]: O[K] } : never;

you can see that DrawerTypes is equivalent to

type DrawerTypes = {
    volunteer: boolean;
    rescues?: undefined;
    map?: undefined;
} | {
    rescues: boolean;
    volunteer?: undefined;
    map?: undefined;
} | {
    map: boolean;
    volunteer?: undefined;
    rescues?: undefined;
}

which is the same as your original definition of DrawerTypes.

Playground


note: key?: undefined is equivalent to key?: never without exactOptionalPropertyTypes.

kelsny
  • 23,009
  • 3
  • 19
  • 48