TypeScript instanceof 类型守卫怎么用

你有没有遇到过这种场景:在代码里把一个不确定类型的变量,拿来调用某个类型专属的方法,结果编译器直接报红?比如你写了个处理用户输入的函数,用户可能传的是字符串,也可能是一个自定义的User类实例,你想判断它是不是User实例,再调用getUserName()方法,这时候就需要用到TypeScript里的instanceof类型守卫了。

先搞懂:什么是类型守卫?

简单说,类型守卫就是给TypeScript编译器的一个“判断依据”——告诉它“到这一步,这个变量的类型已经确定是XX了”。就像你出门前看天气预报,判断“今天要下雨”,然后就会带伞,这个“判断”就是守卫,帮你避免“没带伞被淋”的错误。

TypeScript instanceof 类型守卫怎么用

而instanceof本来是JavaScript用来判断“某个值是不是某个类的实例”的运算符,TypeScript把它变成了类型守卫,相当于给这个老工具加了新功能:它不仅能告诉你“是实例”,还能让编译器自动把这个值的类型收窄到对应类。

举个生活化的例子:判断“是不是奶茶杯”

假设你是奶茶店的打包员,手里拿着一个物品,不确定是“奶茶杯”还是“咖啡杯”,只有奶茶杯有“插吸管”的功能,咖啡杯没有。这时候你可以拿instanceof当“检查工具”:

`typescript

// 先定义两个类,对应不同的杯子

class MilkTeaCup {

drink(): void { console.log("吸珍珠"); }

}

class CoffeeCup {

drink(): void { console.log("喝咖啡"); }

}

// 写一个处理杯子的函数

function handleCup(cup: MilkTeaCup | CoffeeCup) {

// 用instanceof做判断:如果是MilkTeaCup的实例

if (cup instanceof MilkTeaCup) {

// 编译器自动知道这里cup是MilkTeaCup,直接调用drink()不会报错

cup.drink();

} else {

// 剩下的就是CoffeeCup,也可以安全调用它的方法

cup.drink();

}

}

`

要是不用instanceof,直接在if里写cup.drink(),TypeScript会直接报错——因为它不知道当前cup是哪个类的实例,万一你传了其他类型的值,就会出问题。

注意!别踩这个容易错的坑

instanceof只能判断“类的实例”,如果是普通的对象字面量,用它就会失灵。比如你想判断一个{name: "小明"}的对象是不是User类的实例,instanceof会返回false,哪怕这个对象和User实例长得一模一样,因为instanceof看的是“原型链”,不是对象的属性。

再举个反面例子:

`typescript

class User {

name: string;

constructor(name: string) { this.name = name; }

}

// 这是个对象字面量,不是User类的实例

const obj = { name: "小红" };

console.log(obj instanceof User); // 输出false,虽然长得像,但不是实例

// 要是你想判断对象是不是有某个属性,得换别的守卫,比如in守卫,不是instanceof

`

所以记住:instanceof的核心是“看对象是不是某个类new出来的”,不能用来判断普通对象的结构。

总结:`instanceof`类型守卫的用法

它的作用就是帮你在联合类型(比如A | B)的场景下,把不确定的类型“锁定”成具体的类,让编译器能识别你要调用的方法或属性。用的时候就记住三句话:

先明确你要判断的是哪个类;

在`if`里用`变量 instanceof 类名`做判断;

判断后,编译器会自动把变量类型收窄,不用再手动声明。

下次再碰到“不确定类型要调用专属方法”的场景,试试这个小工具,能帮你少踩好多类型错误的坑。

上一篇 C / C++ 语言核心特性与应用场景的知识科普解析