MST

星途 面试题库

面试题:TypeScript泛型类型推断的复杂场景

编写一个泛型函数 `combineArrays`,它接受两个数组作为参数,数组元素类型相同,函数返回一个新数组,新数组由这两个数组的元素交替组成。例如,`combineArrays([1, 2], ['a', 'b'])` 应返回 `[1, 'a', 2, 'b']`。请详细说明在这个函数实现过程中,TypeScript的类型推断是如何确保数组元素类型一致性的,以及如果传入不同类型元素的数组会出现什么问题,该如何解决。
13.4万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试
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类型推断确保数组元素类型一致性的原理

  1. 泛型参数T:在函数定义 combineArrays<T>(arr1: T[], arr2: T[]) 中,T 是一个泛型类型参数。这意味着 arr1arr2 数组的元素类型都被指定为 T。TypeScript 根据调用函数时传入的数组元素类型,自动推断出 T 的具体类型。例如,当调用 combineArrays([1, 2], [3, 4]) 时,TypeScript 推断 Tnumber。这样就确保了两个数组的元素类型是一致的。
  2. 返回类型:函数的返回类型也是 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)

解决方法

  1. 使用联合类型:如果确实需要处理不同类型的数组,可以使用联合类型。例如:
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 的联合类型,允许传入包含 numberstring 类型元素的数组。

  1. 类型断言:在某些特殊情况下,你可能知道传入的数组类型实际上是兼容的,可以使用类型断言,但这种方法需要谨慎使用,因为它绕过了 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;
}

但这种方法会使代码失去类型安全保障,不推荐在大多数情况下使用。一般建议使用联合类型来处理可能不同类型的数组。