I found a solution for this by making use of the never
type in typescript and optional properties.
What I had to do was update my interface declarations in such a that an instance of IRoutableSidebarItem
will never have a children
property and an instance of ITreeSidebarItem
will never have a role
property.
Updated example using the above mentioned workaround:
interface ISidebarCommon {
/**
* The label to be used in sidebar
*/
label: string;
/**
* Icon class in string format for the icon of the sidebar image
*/
icon: string;
}
interface IRoutableSidebarItem extends ISidebarCommon {
/**
* Role number to determine which route to redirect the user to
* This property is mutually exclusive with children
*/
role: number;
children?: never;
}
interface ITreeSidebarItem<SI> extends ISidebarCommon {
/**
* An array of children sidebar items.
* This property is mutually exclusive with role
*/
children: SI[];
role?: never;
}
interface ISidebar {
[index: number]: IRoutableSidebarItem | ITreeSidebarItem<IRoutableSidebarItem
| ITreeSidebarItem<IRoutableSidebarItem>
>;
}
/*
Throws a linting error
*/
const sidebarBroken: ISidebar = [
{
label: 'l1',
icon: 'c1',
role: 5,
children: [
{
label: 'l2',
icon: 'c2',
role: 6,
children: [
{
label: 'l3',
icon: 'c3',
role: 7,
},
],
},
],
},
];
/*
Doesn't throw a linting error
*/
const sidebarWorking: ISidebar = [
{
label: 'l1',
icon: 'c1',
children: [
{
label: 'l2',
icon: 'c2',
children: [
{
label: 'l3',
icon: 'c3',
role: 7,
},
],
},
],
},
{
label: 'l1',
icon: 'c1',
role: 12,
},
];
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…