类型守卫(Type Guards)是 TypeScript 中的一种机制,用于在运行时检查变量的类型,并在代码块中缩小变量的类型范围。类型守卫可以帮助你在编写代码时更安全地处理不同类型的值,避免类型错误。
类型守卫的基本概念
类型守卫通常是一个返回布尔值的表达式或函数,用于检查某个变量是否属于特定的类型。如果类型守卫返回 true
,TypeScript 会在代码块中将变量的类型缩小为特定的类型。
类型守卫的实现方式
TypeScript 提供了多种实现类型守卫的方式,包括:
typeof
类型守卫:用于检查基本类型(如 string
、number
、boolean
等)。
instanceof
类型守卫:用于检查对象是否是某个类的实例。
- 自定义类型守卫函数:通过返回布尔值的函数来实现类型守卫。
in
操作符类型守卫:用于检查对象是否具有某个属性。
示例
1. typeof
类型守卫
typeof
类型守卫用于检查基本类型:
function printValue(value: string | number) {
if (typeof value === "string") {
console.log(`String value: ${value}`);
} else {
console.log(`Number value: ${value}`);
}
}
printValue("hello"); // 输出: String value: hello
printValue(42); // 输出: Number value: 42
在这个例子中,typeof
类型守卫用于检查 value
是否为 string
类型。
2. instanceof
类型守卫
instanceof
类型守卫用于检查对象是否是某个类的实例:
class Dog {
bark() {
console.log("Woof!");
}
}
class Cat {
meow() {
console.log("Meow!");
}
}
function handleAnimal(animal: Dog | Cat) {
if (animal instanceof Dog) {
animal.bark();
} else {
animal.meow();
}
}
const dog = new Dog();
const cat = new Cat();
handleAnimal(dog); // 输出: Woof!
handleAnimal(cat); // 输出: Meow!
在这个例子中,instanceof
类型守卫用于检查 animal
是否是 Dog
类的实例。
3. 自定义类型守卫函数
自定义类型守卫函数通过返回布尔值的函数来实现类型守卫:
interface Bird {
fly(): void;
}
interface Fish {
swim(): void;
}
function isFish(pet: Bird | Fish): pet is Fish {
return (pet as Fish).swim !== undefined;
}
function handlePet(pet: Bird | Fish) {
if (isFish(pet)) {
pet.swim();
} else {
pet.fly();
}
}
const bird: Bird = {
fly() {
console.log("Flying!");
}
};
const fish: Fish = {
swim() {
console.log("Swimming!");
}
};
handlePet(bird); // 输出: Flying!
handlePet(fish); // 输出: Swimming!
在这个例子中,isFish
是一个自定义类型守卫函数,用于检查 pet
是否是 Fish
类型。
4. in
操作符类型守卫
in
操作符类型守卫用于检查对象是否具有某个属性:
interface Car {
drive(): void;
}
interface Boat {
sail(): void;
}
function handleVehicle(vehicle: Car | Boat) {
if ("drive" in vehicle) {
vehicle.drive();
} else {
vehicle.sail();
}
}
const car: Car = {
drive() {
console.log("Driving!");
}
};
const boat: Boat = {
sail() {
console.log("Sailing!");
}
};
handleVehicle(car); // 输出: Driving!
handleVehicle(boat); // 输出: Sailing!
在这个例子中,in
操作符类型守卫用于检查 vehicle
是否具有 drive
属性。
类型守卫的优势
- 类型安全:类型守卫可以帮助你在运行时检查变量的类型,避免类型错误。
- 代码可读性:通过类型守卫,你可以更清晰地表达代码的意图,提高代码的可读性。
- 类型缩小:类型守卫可以在代码块中缩小变量的类型范围,使得类型检查更加精确。
总结
类型守卫是 TypeScript 中用于在运行时检查变量类型并缩小类型范围的机制。通过 typeof
、instanceof
、自定义类型守卫函数和 in
操作符,你可以实现类型守卫,确保代码的类型安全性和可读性。理解类型守卫的使用场景和实现方式,可以帮助你编写出更安全、更易维护的代码。