面试题答案
一键面试function combineArrays<T>(arr1: T[], arr2: T[]): T[] {
const result: T[] = [];
const length = Math.max(arr1.length, arr2.length);
for (let i = 0; i < length; i++) {
if (arr1[i]!== undefined) {
result.push(arr1[i]);
}
if (arr2[i]!== undefined) {
result.push(arr2[i]);
}
}
return result;
}
TypeScript类型推断确保数组元素类型一致性的原理
- 泛型参数T:在函数定义
combineArrays<T>(arr1: T[], arr2: T[])
中,T
是一个泛型类型参数。这意味着arr1
和arr2
数组的元素类型都被指定为T
。TypeScript 根据调用函数时传入的数组元素类型,自动推断出T
的具体类型。例如,当调用combineArrays([1, 2], [3, 4])
时,TypeScript 推断T
为number
。这样就确保了两个数组的元素类型是一致的。 - 返回类型:函数的返回类型也是
T[]
,这保证了返回的新数组元素类型与传入数组的元素类型一致。
传入不同类型元素数组的问题
如果传入不同类型元素的数组,比如 combineArrays([1, 2], ['a', 'b'])
,TypeScript 会报错,因为 number
类型和 string
类型不兼容。错误信息大致如下:
Argument of type 'number[]' is not assignable to parameter of type'string[]'.
Type 'number' is not assignable to type'string'.(2345)
解决方法
- 使用联合类型:如果确实需要处理不同类型的数组,可以使用联合类型。例如:
function combineArraysWithUnion(arr1: (number | string)[], arr2: (number | string)[]): (number | string)[] {
const result: (number | string)[] = [];
const length = Math.max(arr1.length, arr2.length);
for (let i = 0; i < length; i++) {
if (arr1[i]!== undefined) {
result.push(arr1[i]);
}
if (arr2[i]!== undefined) {
result.push(arr2[i]);
}
}
return result;
}
这里将数组元素类型定义为 number | string
的联合类型,允许传入包含 number
或 string
类型元素的数组。
- 类型断言:在某些特殊情况下,你可能知道传入的数组类型实际上是兼容的,可以使用类型断言,但这种方法需要谨慎使用,因为它绕过了 TypeScript 的类型检查。例如:
function combineArraysWithAssertion(arr1: any[], arr2: any[]): any[] {
const result: any[] = [];
const length = Math.max(arr1.length, arr2.length);
for (let i = 0; i < length; i++) {
if (arr1[i]!== undefined) {
result.push(arr1[i] as number); // 这里假设元素类型实际兼容
}
if (arr2[i]!== undefined) {
result.push(arr2[i] as number);
}
}
return result;
}
但这种方法会使代码失去类型安全保障,不推荐在大多数情况下使用。一般建议使用联合类型来处理可能不同类型的数组。