我有一个JS函数,它接受一个数组(长度相同,但类型不同),以及一个键名数组(第一个参数中每个数组一个),并将数组合并到一个对象数组中。如下所示:
const mergeArraysToSeries = (arrs, keys) => {
const merged = [];
for (let dataIndex = 0; dataIndex < arrs[0].length; dataIndex++) {
const el = keys.reduce((combined, currKey, keyIndex) => {
const val = arrs[keyIndex][dataIndex];
return { ...combined, [currKey]: val };
}, {});
merged.push(el);
}
return merged;
}
const example = mergeArraysToSeries([[1,2,3], ['a','b','c']], ['num', 'letter'])
// example = [{num: 1, letter: 'a'}, {num: 2, letter: 'b'}, {num: 3, letter: 'c'}]
是否有一种方法可以在TypeScript中实现合并数组的自动完成,并正确地映射每个键的类型?对于上面的示例,我希望编译器知道example[0].num
的类型是'number'
我已经到了一个可以让自动完成/编译器检查结果数组中每个项的属性名称的地方,但是我不知道如何为每个元素获得正确的类型。类型签名现在看起来是这样的:
const mergeArrayToSeries = <K>(arrs: any[][], keys: (keyof K)[]): Record<keyof K, any>[] => ...
是否有一种很好的方法来删除传递的数组的any
,并具有上面描述的类型安全性?
谢谢!
编辑:如果可能的话,我希望它可以用于任意数量的数组。
发布于 2020-07-08 00:06:48
你可以使用像这样的签名:
declare function mergeArraysToSeries<
T extends any[],
U extends any[],
P1 extends string,
P2 extends string
>(arrays: [T, U], properties: [P1, P2]): {
[K in P1]: T[number]
} & {
[K in P2]: U[number]
}[];
const example = mergeArraysToSeries([[1,2,3], ['a','b','c']], ['num', 'letter']); // example is { num: number; letter: string }[]
更新
如果需要支持两个以上的数组,则可以添加更多的重载。
declare function mergeArraysToSeries<T, U, P extends readonly string[]>(arrays: [T[], U[]], properties: P): { [K in P[0]]: T } & { [K in P[1]]: U }[]
declare function mergeArraysToSeries<T, U, V, P extends readonly string[]>(arrays: [T[], U[], V[]], properties: P): { [K in P[0]]: T } & { [K in P[1]]: U } & { [K in P[2]]: V }[]
declare function mergeArraysToSeries<T, U, V, W, P extends readonly string[]>(arrays: [T[], U[], V[], W[]], properties: P): { [K in P[0]]: T } & { [K in P[1]]: U } & { [K in P[2]]: V } & { [K in P[3]]: W }[]
const two = mergeArraysToSeries([[1, 2, 3], ['a', 'b', 'c']], ['num', 'letter'] as const)
const three = mergeArraysToSeries([[1, 2, 3], ['a', 'b', 'c'], ['foo', 'bar', 'baz']], ['num', 'letter', 'other'] as const)
const four = mergeArraysToSeries([[1, 2, 3], ['a', 'b', 'c'], ['foo', 'bar', 'baz'], [0, 0, 0]], ['num', 'letter', 'other', 'index'] as const)
https://stackoverflow.com/questions/62784843
复制相似问题