Typescript合并n个对象数组



我有一个名为IndexedObjecttype,它被定义为:

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

我使用它的原因是,我有一个输入数组,以及几个转换和过滤它的函数,我需要跟踪每个元素的原始索引(这在主要问题中可能不重要,但我解释了它,以防万一(

因此,我有任意数量的IndexedObject<T1>[]IndexedObject<T2>[]等类型的数组,其中T1T2等是具有任意键的不同对象类型。我想把它们合并成一个合并对象的数组。例如:

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'}
]

合并本身不是问题。这是我写的函数:

function mergeIndexedArrays(...arrays: IndexedObject[][]) {
return arrays.reduce((result, array) => {
for (let a of array) {
result[a._i] = { ...result[a._i], ...a }
}
return result
}, [])
}

问题出在打字上。我需要merge函数的返回类型来动态地包含所有输入类型的键(这里是T1T2(。我该怎么做?

请注意,有任意数量的数组。

我试着用variadic tuple types来实现这一点,但我想不通。

谢谢

本质上,我们想要"提取物";索引对象(infer(中的所有类型,然后将它们相交在一起(并使结果为Partial,因为它们不能保证存在(。

type UnionToIntersection<U> = 
(U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never;
type InferTypes<A> = A extends IndexedObject<infer U>[][] ? U : never;
function mergeIndexedArrays<Arrays extends IndexedObject[][]>(...arrays: Arrays): Partial<UnionToIntersection<InferTypes<Arrays>>>[];
function mergeIndexedArrays(...arrays: IndexedObject[][]) {
return arrays.reduce((result, array) => {
for (let a of array) {
result[a._i] = { ...result[a._i], ...a }
}
return result
}, [])
}

然后我们可以使用rest参数将所有数组收集到泛型类型Arrays中。此外,我已经将签名移动到重载中,这样它就不会在函数体中导致令人讨厌的类型错误。

游乐场

最新更新