I have an enum:
export enum Sections {
Dashboard = "Dashboard",
Select = "Select",
Widget = "Widget",
}
I want to build a prop for my react components that is a discriminating union type.
export type ReduxLocation =
| {
path: Sections;
widget?: never;
}
| {
path: Sections.Widget;
widget: {
id: string;
side?: "left" | "right";
};
};
Then one of the props of a react component would be of type ReduxLocation:
const MyComponent: React.FC<{ reduxLocation: ReduxLocation }> = () => {
// return whatever
}
The goal is that if passing a reduxLocation with a path of any of the Sections, no other entry is required in the reduxLocation object. However, if path is Sections.Widget, then the widget entry is required.
const App = () => {
return (
<div>
<MyComponent
reduxLocation={{
path: Sections.Dashboard
}}
/>
<MyComponent
reduxLocation={{
path: Sections.Dashboard,
widget: { id: 'id' } // <---- errors as expected
}}
/>
<MyComponent
reduxLocation={{
path: Sections.Widget,
widget: { id: 'id' }
}}
/>
<MyComponent
reduxLocation={{
path: Sections.Widget
// <-------------------------- should error but doesnt
}}
/>
</div>
);
}
In the case of the last MyComponent above, I am not getting the desired TS error that when using a path: Sections.Widget, the widget property is then also required. My guess is because using path: Sections.Widget also satisfies the first type in ReduxLocation, as path is still of type Maps.
How can I achieve the desired result, where the above case enforces the correct combination of properties in the prop?