MST
星途 面试题库

面试题:TypeScript类声明值与类型的深入应用

假设有一个复杂的业务场景,需要创建一个包含多个类继承关系且带有泛型的TypeScript项目。请解释在这种情况下,类声明的值和类型是如何相互作用并保持类型安全的。同时,编写一段代码展示如何利用类声明的类型进行复杂数据结构的操作。
18.7万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

类声明的值和类型相互作用及类型安全

  1. 类型声明:在TypeScript中,类声明既定义了值(实例),也定义了类型。类的属性和方法在声明时指定类型,这使得编译器能够在编译阶段检查类型的正确性。例如,如果一个类Animal有一个name属性且类型为string,那么任何试图给name赋非字符串值的操作都会被编译器报错。
  2. 继承关系中的类型安全:当存在类继承关系时,子类必须满足父类的类型契约。子类可以扩展父类的属性和方法,但不能改变它们的类型(除非使用更具体的类型)。例如,若Dog类继承自Animal类,Dog类的实例必须具有Animal类定义的所有属性和方法,并且类型要兼容。
  3. 泛型的作用:泛型允许我们在类声明中定义类型变量,从而在使用类时指定具体的类型。这增强了代码的复用性和类型安全性。例如,一个Stack<T>类可以存储任何类型T的数据,但在使用时,比如const stack = new Stack<number>(),编译器就会确保stack只能操作number类型的数据。

代码示例

// 定义一个泛型类
class Node<T> {
    value: T;
    next: Node<T> | null;

    constructor(value: T) {
        this.value = value;
        this.next = null;
    }
}

// 定义一个链表类,包含多个Node节点
class LinkedList<T> {
    head: Node<T> | null;

    constructor() {
        this.head = null;
    }

    add(value: T) {
        const newNode = new Node(value);
        if (!this.head) {
            this.head = newNode;
        } else {
            let current = this.head;
            while (current.next) {
                current = current.next;
            }
            current.next = newNode;
        }
    }

    getValues(): T[] {
        const values: T[] = [];
        let current = this.head;
        while (current) {
            values.push(current.value);
            current = current.next;
        }
        return values;
    }
}

// 使用链表类操作复杂数据结构
const numberList = new LinkedList<number>();
numberList.add(1);
numberList.add(2);
numberList.add(3);

const numbers = numberList.getValues();
console.log(numbers); // 输出: [1, 2, 3]

const stringList = new LinkedList<string>();
stringList.add('a');
stringList.add('b');
stringList.add('c');

const strings = stringList.getValues();
console.log(strings); // 输出: ['a', 'b', 'c']

在上述代码中,Node类和LinkedList类都使用了泛型T,使得它们可以存储任何类型的数据。通过在使用时指定具体类型(如numberstring),编译器可以确保对链表的操作都是类型安全的。