I have a type named IndexedObject, which is defined as:
type IndexedObject<T extends {} = { [k: string]: any }> = T & { _i: number }
// It just appends an index "_i" to the object
// The "_i" index is assigned in the first function of the chain,
// and then it doesn't get changed anywhere else
The reason I use this is that I have an input array, and several functions that transform and filter it, and I need to keep track of the original index of each element (it's probably not important in the main question, but I explained it just in case)
So I have an arbitrary number of arrays of type IndexedObject<T1>[], IndexedObject<T2>[], etc., with T1, T2, etc. being different object types with arbitrary keys. And I want to merge them into one array of merged objects. for example:
interface T1 {
id: number
name: string
}
interface T2 {
status: boolean
message: string
}
let arr1: IndexedObject<T1>[] = [
{_i: 0, id: 201, name: 'a'},
{_i: 3, id: 5, name: 'h'}
]
let arr2: IndexedObject<T2>[] = [
{_i: 0, status: true, message: '1234'},
{_i: 1, status: false, message: '5678'},
{_i: 4, status: false, message: '9065'}
]
// merged:
let merged = [
{_i: 0, id: 201, name: 'a', status: true, message: '1234'},
{_i: 1, status: false, message: '5678'},
{_i: 3, id: 5, name: 'h'},
{_i: 4, status: false, message: '9065'}
]
The merging itself is not an issue. This is the function I wrote:
function mergeIndexedArrays(...arrays: IndexedObject[][]) {
return arrays.reduce((result, array) => {
for (let a of array) {
result[a._i] = { ...result[a._i], ...a }
}
return result
}, [])
}
The problem is with typing. I need the return type of the merge function to dynamically contain the keys of all the input types (here T1 and T2). How can I do this?
Note that there are an arbitrary number of arrays.
I tried to achieve this using variadic tuple types but I couldn't figure it out.
Thank you