I'm trying to define a function that maps an object fields.
For instance, a tree can be stored as object. Tree node identifiers are stored as object keys. Tree nodes are stored as object field values. Each node can have an array of children identifiers.
The following function removes an item with a scpecified id from tree and also removes it from parent's children collection (for simplicity it doesn't remove children of children and so on):
type Tree = { [id: string]: { children?: string[] } };
function removeItem<T extends Tree>(tree: T, itemId: string): T {
return Object.fromEntries(Object.entries(tree)
.filter(([id, item]) => id !== itemId)
.map(([id, item]) => [id, { ...item, children: item.children?.filter(child => child !== itemId) }]));
}
The usage example:
type CustomTree = { [id: string]: { name: string, children: string[] } };
const tree1: CustomTree = {};
const tree2: CustomTree = removeItem(tree1, '123');
The function should be able to process objects of a more restricted types (for instance, CustomTree).
The problem is that I get the following type error:
Type '{ [k: string]: { children: string[]; }; }' is not assignable to type 'T'.
'{ [k: string]: { children: string[]; }; }' is assignable to the constraint of type 'T',
but 'T' could be instantiated with a different subtype of constraint 'Tree'.
How to fix it?