类型守卫(Type Guards)是一种在 TypeScript 中用于检查变量类型的技术,它使得开发者能够在运行时更精确地判断和操作不同类型的值。类型守卫可以通过不同的手段来缩小变量的类型范围,使得 TypeScript 能够更准确地理解代码中的类型。
以下是一些常见的类型守卫技术,也被称为类型保护(Type Guards):
1. typeof 类型守卫
使用 typeof
来检查变量的类型,例如:
function logValue(value: string | number) {
if (typeof value === "string") {
console.log(value.toUpperCase()); // 在这个块中,value 被缩小为 string 类型
} else {
console.log(value.toFixed(2)); // 在这个块中,value 被缩小为 number 类型
}
}
- 这个函数
logValue
接受一个参数value
,该参数可以是string
或number
类型。 - 使用
typeof value === "string"
条件来检查value
的类型。在每个分支中,value
被缩小为相应的类型,使得在块内可以安全地调用该类型的方法。
2. instanceof 类型守卫
使用 instanceof
来检查对象是否是某个类的实例,例如:
class Cat {
meow() {
console.log("喵喵!");
}
}
class Dog {
bark() {
console.log("汪汪!");
}
}
function petSound(pet: Cat | Dog) {
if (pet instanceof Cat) {
pet.meow(); // 在这个块中,pet 被缩小为 Cat 类型
} else {
pet.bark(); // 在这个块中,pet 被缩小为 Dog 类型
}
}
- 有两个类
Cat
和Dog
,以及一个函数petSound
接受一个参数pet
,该参数可以是Cat
或Dog
类型。 - 使用
pet instanceof Cat
和pet instanceof Dog
来检查pet
的实际类型,从而在每个分支中缩小pet
的类型范围。
3. in 操作符类型守卫
使用 in
操作符来检查对象是否包含某个属性,例如:
interface Bird {
fly(): void;
}
interface Fish {
swim(): void;
}
function movePet(pet: Bird | Fish) {
if ("fly" in pet) {
pet.fly(); // 在这个块中,pet 被缩小为 Bird 类型
} else {
pet.swim(); // 在这个块中,pet 被缩小为 Fish 类型
}
}
- 有两个接口
Bird
和Fish
,以及一个函数movePet
接受一个参数pet
,该参数可以是Bird
或Fish
类型。 - 使用
"fly" in pet
来检查pet
是否包含fly
属性,根据检查结果缩小pet
的类型范围。
4. 自定义类型守卫函数
使用自定义的类型守卫函数,例如:
interface Bird {
fly(): void;
}
interface Fish {
swim(): void;
}
function isBird(pet: Bird | Fish): pet is Bird {
return (pet as Bird).fly !== undefined;
}
function movePet(pet: Bird | Fish) {
if (isBird(pet)) {
pet.fly(); // 在这个块中,pet 被缩小为 Bird 类型
} else {
pet.swim(); // 在这个块中,pet 被缩小为 Fish 类型
}
}
- 有两个接口
Bird
和Fish
,以及一个自定义函数isBird
,用于检查是否是Bird
类型。 - 在
movePet
函数中使用isBird(pet)
,根据自定义的类型守卫函数的结果缩小pet
的类型范围。