MST
星途 面试题库

面试题:TypeScript类型推断、类型注解与类型兼容性的深度理解

考虑以下TypeScript代码片段: ```typescript interface Animal { name: string; } interface Dog extends Animal { bark(): void; } function handleAnimal(animal: Animal) { console.log('Handling animal:', animal.name); } function handleDog(dog: Dog) { dog.bark(); handleAnimal(dog); } ``` 1. 解释为什么在`handleDog`函数中可以将`Dog`类型的实例传递给`handleAnimal`函数,这体现了TypeScript中类型兼容性的哪些原则? 2. 如果我们希望在`handleAnimal`函数中,根据传入对象的实际类型(如果是`Dog`类型)调用`bark`方法,应该如何结合类型推断和类型注解来实现这一功能?请详细说明实现思路和代码修改。
45.7万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试
  1. 解释为什么在handleDog函数中可以将Dog类型的实例传递给handleAnimal函数以及体现的类型兼容性原则
    • 在TypeScript中,这体现了里氏替换原则Dog接口继承自Animal接口,这意味着Dog类型是Animal类型的子类型。根据里氏替换原则,子类型必须能够替换它们的父类型。所以,任何期望Animal类型的地方,都可以接受Dog类型,因为Dog包含了Animal的所有属性(在这个例子中就是name属性)。
  2. handleAnimal函数中根据传入对象的实际类型(如果是Dog类型)调用bark方法的实现思路和代码修改
    • 实现思路
      • 使用类型断言来明确告诉TypeScript编译器某个对象的类型。
      • 或者使用instanceof操作符来进行运行时类型检查,结合类型推断。
    • 代码修改(使用类型断言)
interface Animal {
    name: string;
}
interface Dog extends Animal {
    bark(): void;
}
function handleAnimal(animal: Animal) {
    console.log('Handling animal:', animal.name);
    if ('bark' in animal) {
        (animal as Dog).bark();
    }
}
function handleDog(dog: Dog) {
    dog.bark();
    handleAnimal(dog);
}
  • 代码修改(使用instanceof,假设Dog是一个类)
class Animal {
    constructor(public name: string) {}
}
class Dog extends Animal {
    bark() {
        console.log('Woof!');
    }
}
function handleAnimal(animal: Animal) {
    console.log('Handling animal:', animal.name);
    if (animal instanceof Dog) {
        animal.bark();
    }
}
function handleDog(dog: Dog) {
    dog.bark();
    handleAnimal(dog);
}