Here is a simple function that constructs a tree structure.
interface CommonItem {
id: string
parent: string | null
}
interface CommonTreeItem {
children: CommonTreeItem[]
}
export const generateTree = <Item extends CommonItem, TreeItem extends CommonTreeItem & Item>(
data: Item[]
): TreeItem[] => {
const root: TreeItem[] = []
const dataMap = new Map<string, TreeItem>()
for (const item of data) {
dataMap.set(item.id, {...item, children: []})
// ~~~~~~~~~~~~~~~~~~~~~~~~
// TS2345: Argument of type 'Item & { children: never[]; }' is not assignable to parameter of type 'TreeItem'.
}
for (const originalItem of data) {
if (originalItem.parent) {
const parentItem = dataMap.get(originalItem.parent)
const item = <TreeItem>dataMap.get(originalItem.id)
if (parentItem) {
parentItem.children.push(item)
}
} else {
root.push(
<TreeItem>dataMap.get(originalItem.id)
)
}
}
return root
}
The linter is throwing errors and I'm unsure why. I attempted to create generic types with Item but it didn't work out. Perhaps there's a need to construct TreeItem in a different manner!?