I am relatively new to typescript and need some advice on how best to type an object structure like the one below. I want to be able to specify which item ids are allowed to be in a section based on a section id.
I realize this question might be vague, but really what I am looking for is for someone to point me in the right direction. If I need to totally re-type this object in a different way using some other typescript syntax, that is fine too. At this point, I am not sure what to Google or what I need to study about typescript to understand the best way to type an object like this.
Any help would be appreciated.
type ItemBase = {
common: string | number
}
type Item = ItemBase & ({
id: 'item1',
custom1: string
} | {
id: 'item2',
custom1: number,
custom2: string,
})
type SectionBase = {
common: string | number
}
type Section = SectionBase & ({
id: 'section1',
items: {
[key in Section1ItemIds]: Item
},
} | {
id: 'section2',
items: {
[key in Section2ItemIds]: Item
},
})
type Section1ItemIds = 'item1';
type Section2ItemIds = 'item1' | 'item2';
type Group = {
sections: {
[key in Section['id']]: Section
}
}
const group: Group = {
sections: {
section1: {
id: 'section1',
common: '',
items: {
item1: {
id: 'item1',
common: '',
custom1: ''
}
}
},
section2: {
id: 'section2',
common: 0,
items: {
item1: {
id: 'item1',
common: '',
custom1: ''
},
item2: {
id: 'item2',
common: '',
custom1: 0,
custom2: ''
}
}
}
}
}
const sectionIds = Object.keys(group.sections) as Array<keyof typeof group.sections>;
const sectionId = sectionIds[Math.floor(Math.random()*sectionIds.length)]
const section: Section = group[sectionId];
const getItemIds = (): (keyof typeof section.items)[] => {
switch(section.id){
case 'section1': return ['item1'];
case 'section2': return ['item1','item2'];
}
}