- 解释为什么在
handleDog
函数中可以将Dog
类型的实例传递给handleAnimal
函数以及体现的类型兼容性原则:
- 在TypeScript中,这体现了里氏替换原则。
Dog
接口继承自Animal
接口,这意味着Dog
类型是Animal
类型的子类型。根据里氏替换原则,子类型必须能够替换它们的父类型。所以,任何期望Animal
类型的地方,都可以接受Dog
类型,因为Dog
包含了Animal
的所有属性(在这个例子中就是name
属性)。
- 在
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);
}