MST

星途 面试题库

面试题:复杂类型兼容性及类型检查在TypeScript中的深度剖析

考虑如下场景,有一个泛型类`class Box<T> { value: T; constructor(v: T) { this.value = v; } }`,以及两个类型`type NumArray = number[]`和`type AnyArray = Array<any>`。现在有`let box1: Box<NumArray>; let box2: Box<AnyArray>;`,能否进行`box1 = box2;`这样的赋值操作?如果不能,如何通过类型检查和类型兼容性的知识来实现一个类似的功能,使得在安全的前提下,尽可能复用代码并满足这样的赋值需求(例如,在某些情况下可以将`Box<AnyArray>`的实例赋值给`Box<NumArray>`类型的变量),请详细阐述思路并给出代码示例。
20.4万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试
  1. 能否直接赋值
    • 不能直接进行box1 = box2;这样的赋值操作。在TypeScript中,Box<NumArray>Box<AnyArray>是不同的类型,虽然AnyArray可以包含NumArray类型的值,但类型系统不允许这样直接赋值,因为这可能会引入类型安全问题。例如,如果后续对box1进行操作,期望其valuenumber[]类型,但由于赋值了Box<AnyArray>,可能会导致传入非number[]类型的值。
  2. 实现类似功能的思路
    • 可以通过类型断言和类型检查来实现类似功能。首先,需要检查Box<AnyArray>中的value是否确实是number[]类型。如果是,则可以安全地进行赋值。
    • 我们可以定义一个函数来执行这种类型检查和赋值操作,这样可以复用代码并且保证类型安全。
  3. 代码示例
class Box<T> {
    value: T;
    constructor(v: T) {
        this.value = v;
    }
}
type NumArray = number[];
type AnyArray = Array<any>;
function assignBoxes<U, V>(src: Box<U>, target: Box<V>): boolean {
    if (Array.isArray(src.value) && src.value.every((element) => typeof element === 'number')) {
        // 类型断言,因为已经检查过src.value是number[]类型
        target.value = src.value as unknown as V;
        return true;
    }
    return false;
}
let box1: Box<NumArray> = new Box<NumArray>([1, 2, 3]);
let box2: Box<AnyArray> = new Box<AnyArray>([4, 5, 6]);
if (assignBoxes(box2, box1)) {
    console.log('赋值成功', box1.value);
} else {
    console.log('赋值失败');
}

在上述代码中,assignBoxes函数接收两个Box实例,检查源Boxvalue是否为number[]类型。如果是,则通过类型断言将其赋值给目标Box,并返回true;否则返回false。这样在安全的前提下实现了类似将Box<AnyArray>实例赋值给Box<NumArray>变量的功能。