I need help sorting a nested array using a generic function. The sorting should be based on the values of the items within the nested array.
Here is an example of my array:
type Person = {
id: number,
name: string,
childs: Child[]
}
type Child = {
id: number,
name: string,
}
const persons : Person[] = [
{
id: 1, name: 'Person 1',
childs:[
{id: 1, name: 'Child 1'},
{id: 2, name: 'Child 2'}
]
},
{
id: 2, name: 'Person 2',
childs:[
{id: 1, name: 'Child 1'},
]
},
{
id: 3, name: 'Person 3',
childs:[
{id: 1, name: 'Child 1'},
{id: 2, name: 'Child 2'}
{id: 3, name: 'Child 3'}
]
},
];
To achieve this sorting, I want to use my sort function as follows:
sortNestedArrays(persons, 'childs', 'name');
This means sorting the nested array 'childs' by the property 'name'.
My current approach
I have been struggling with the correct syntax for this function for quite some time now.
type ArrayElement<ArrayType extends readonly unknown[]> =
ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
type KeysMatching<T, V> = {[K in keyof T]-?: T[K] extends V ? K : never}[keyof T];
/**
* @param array Main array.
* @param keyOfSubArray Key pointing to elements that lead to the value of the nested array.
* @param propertyName Property by which the nested array is sorted.
*/
function sortNestedArrays<A, K extends KeysMatching<A, unknown[]>>(array: A[], keyOfSubArray: K, propertyName: ???){
array.forEach((member) => {
const nestedArray = member[keyOfSubArray];
nestedArray.forEach((nestedMember) => {
});
});
}
This is where I currently stand. By using KeysMatching
, I was able to ensure that the argument keyOfSubArray
only accepts keys that are arrays, allowing safe access to the nested array.
However, Typescript does not understand the following lines. Since keyOfSubArray
can only be a key that points to an array, it follows that member[keyOfSubArray]
must also be an array. Yet, the compiler produces the error message:
Property 'forEach' does not exist on type 'A[K]'.
const nestedArray = member[keyOfSubArray];
nestedArray.forEach((nestedMember) => {
});
My questions at this point
1) Why doesn't the compiler recognize that member[keyOfSubArray]
must be an array and how can I resolve this issue?
2) Next, I need to define the argument propertyName
, which must be a key within the items of the subarray (keyof Child
). How can I properly define this as a generic within the function?