TypeScript:多类型数组联动排序时如何保留原数组类型
解决TypeScript多类型数组联动排序的类型兼容问题
原函数使用单一泛型T,导致传入不同类型的数组时(比如number[]和string[]),TypeScript会要求所有数组的元素类型统一,从而抛出Number[] is not assignable to string[]的错误。要保留返回值的原数组类型顺序,需要改用元组泛型来实现类型的精准推断。
修改后的函数实现
export function sortArraysTogether<T extends any[]>( arrays: T, comparator: (a: T[0][number], b: T[0][number]) => number = (a, b) => { if (a < b) return -1; if (a > b) return 1; return 0; } ): T { if (arrays.length === 0) return arrays; // 基于第一个数组生成排序后的索引序列 const firstArr = arrays[0]; const sortedIndices = firstArr .map((_, idx) => idx) .sort((i, j) => comparator(firstArr[i], firstArr[j])); // 按排序索引重新排列所有数组 return arrays.map(arr => sortedIndices.map(idx => arr[idx])) as T; }
关键修改点说明
- 泛型约束改为元组类型:
T extends any[]让TypeScript将输入的数组参数推断为元组(比如[number[], string[]]),而非统一的T[][],这样每个数组元素的类型可以独立存在。 - 比较器类型绑定第一个数组:
T[0][number]提取第一个数组的元素类型,确保比较逻辑的参数类型和排序依据的数组完全匹配,避免类型不兼容。 - 返回类型匹配输入元组:返回类型指定为
T,保证输出结构和输入的元组类型完全一致,保留原数组的类型顺序。
使用示例
// 输入元组类型为 [number[], string[]] const sortedResult = sortArraysTogether([[20, 10, 30], ['bob', 'alice', 'charlie']]); // sortedResult 的类型会被推断为 [number[], string[]],符合预期 console.log(sortedResult); // 输出:[[10, 20, 30], ['alice', 'bob', 'charlie']]
原函数问题根源
原函数的T[][]类型会让TypeScript尝试推断一个所有数组元素都兼容的公共类型T,但number和string没有公共兼容类型,因此触发类型错误。改用元组泛型后,每个数组的类型被独立追踪,自然解决了类型冲突问题。
内容的提问来源于stack exchange,提问作者user26359422
相关产品推荐
相关产品推荐

