I'm trying to write a function that merges, and sorts already sorted arrays into one sorted array. It accepts array of array of objects, and a key to compare which will be the base of the comparison. I need to make sure that the value of the provided key is always a number.
Here's what I'm at so far:
const sortMerge = <
A extends Array<I>,
K extends keyof A[number],
I = A[number] & {
[key in K]: number;
},
>(
arrays: A[],
key: K,
sortMethod = SortMethod.asc,
) => {
const indexesOfArrays = arrays.map(() => 0);
const mergedSorted = [];
while (arrays.some((array, i) => array.length > indexesOfArrays[i])) {
const currentItemsOfArrays = arrays.map(
(array, arrayIndex) => array[indexesOfArrays[arrayIndex]],
);
const comparison = currentItemsOfArrays.map((item) =>
item ? item[key] : (sortMethod === SortMethod.asc ? Infinity : -Infinity),
);
const nextArrayIndex = comparison.indexOf(
Math[sortMethod === SortMethod.asc ? 'min' : 'max'](...comparison),
);
const nextItem = currentItemsOfArrays[nextArrayIndex];
mergedSorted.push(nextItem);
indexesOfArrays[nextArrayIndex]++;
}
return mergedSorted;
};
Everything's fine, but it doesn't recognise I[K] as number, but that's what I was trying to do with defining both K, and I as generics.
What am I doing wrong?
Expected errors/types:
const missingKey = [ { a: 1 } ];
const valid = [ { a: 2, b: 3 } ];
const anotherValid = [ { c: 3, b: 4 } ];
sortMerge([missingKey, valid], 'b') // missingKey[number] is missing property 'b';
sortMerge([valid, anotherValid], 'b') // expected return type: ({ a: number, b: number } | { c: number, b: number })[]