TypeScript - 类型守卫:初学者指南

你好,未来的编程巨星!? 我很激动能成为你探索TypeScript和类型守卫世界的向导。作为一个教计算机科学多年的老师,我可以告诉你,理解类型守卫就像在TypeScript宇宙中拥有超能力。那么,让我们一起来解锁这个力量吧!

TypeScript - Type Guards

类型守卫是什么?

在我们深入细节之前,先来了解一下类型守卫是什么。想象你在一个豪华派对上担任保安。你的工作是检查每个嘉宾的邀请函,确保他们在正确的区域。TypeScript中的类型守卫做着类似的工作 - 它们帮助编译器在特定的代码块内检查和缩小变量的类型。

现在,让我们来探索今天我们将要学习的三种主要类型守卫:

类型守卫 描述
typeof 检查变量的类型
in 检查对象中是否存在某个属性
instanceof 检查对象是否是某个类的实例

TypeScript中的'typeof'类型守卫

'typeof'类型守卫就像在问,“你是什么东西?”它用于检查变量的类型。让我们来看一个例子:

function printAll(strs: string | string[] | null) {
if (typeof strs === "object") {
for (const s of strs) {
console.log(s);
}
} else if (typeof strs === "string") {
console.log(strs);
} else {
// 无需操作
}
}

在这个例子中,我们使用typeof来检查strs是否是对象(这包括数组)或者字符串。如果是对象,我们就遍历它。如果是字符串,我们就直接打印。

这里有一个有趣的记忆方法:想象你在宠物店,想知道一个动物是狗还是猫。你可能会问,“你是哪种动物?”这正是TypeScript中的typeof所做的!

TypeScript中的'in'类型守卫

'in'类型守卫就像在问,“你有这个特性吗?”它检查对象中是否存在某个属性。让我们来看一个例子:

type Fish = { swim: () => void };
type Bird = { fly: () => void };

function move(animal: Fish | Bird) {
if ("swim" in animal) {
animal.swim();
} else {
animal.fly();
}
}

在这段代码中,我们检查animal是否有swim属性。如果有,我们假设它是Fish并调用swim方法。如果没有,我们假设它是Bird并调用fly方法。

可以这样想:如果你在尝试确定你的新宠物是鱼还是鸟,你可能会检查它是否有鳍。这就是'in'类型守卫所做的 - 它检查一个特性属性。

TypeScript中的'instanceof'类型守卫

'instanceof'类型守卫就像在问,“你是这个家族的成员吗?”它检查对象是否是特定类的实例。这里有一个例子:

class Bird {
fly() {
console.log("飞翔...");
}
}

class Fish {
swim() {
console.log("游泳...");
}
}

function move(pet: Bird | Fish) {
if (pet instanceof Bird) {
pet.fly();
} else {
pet.swim();
}
}

let myBird = new Bird();
move(myBird); // 输出:飞翔...

在这个例子中,我们检查pet是否是Bird类的实例。如果是,我们调用fly方法。如果不是,我们假设它是Fish并调用swim方法。

想象你在家族聚会上,试图确定某人是否是约翰逊家族的一员。你可能会问,“你是约翰逊吗?”这正是TypeScript中的instanceof所做的!

一切结合

现在我们已经学习了这三种类型守卫,让我们看看如何将它们全部结合使用:

class Car {
drive() { console.log("嗡嗡!"); }
}

class Bicycle {
ride() { console.log("踩踏!"); }
}

type Vehicle = Car | Bicycle | string;

function useVehicle(vehicle: Vehicle) {
if (typeof vehicle === "string") {
console.log(`车辆是:${vehicle}`);
} else if (vehicle instanceof Car) {
vehicle.drive();
} else if ("ride" in vehicle) {
vehicle.ride();
} else {
console.log("未知车辆类型");
}
}

useVehicle("滑板");  // 输出:车辆是:滑板
useVehicle(new Car());     // 输出:嗡嗡!
useVehicle(new Bicycle()); // 输出:踩踏!

在这个例子中,我们使用了所有三种类型守卫:

  1. 我们使用typeof来检查车辆是否是字符串。
  2. 我们使用instanceof来检查它是否是Car。
  3. 我们使用in来检查它是否有ride方法(这表明它是Bicycle)。

这就像是一个超级侦探,使用所有的技能来确定你正在处理的车辆的确切类型!

结论

就这样,我的编程学徒们!我们已经穿越了TypeScript类型守卫的土地,探索了typeofininstanceof守卫。这些强大的工具将帮助你们编写更安全、更可预测的代码,通过让TypeScript更好地理解你的意图。

记住,使用类型守卫就像和你的代码进行友好的对话。你只是在问它问题,以便更好地理解它。所以下次你编程时,不要害羞 - 用这些类型守卫和你的变量开始聊天吧!

继续练习,保持好奇心,不久之后,你就会像一个专业人士一样守护类型。下次见,快乐编程!??

Credits: Image by storyset