TypeScript in 类型守卫怎么用

TypeScript 里的类型守卫,听起来像是个有点复杂的编程术语,其实你可以把它理解成“给代码装个智能过滤器”——当你处理多个不同类型的数据时,它能帮你提前“筛掉”不符合要求的类型,避免程序出乱子,而且全程都是用生活化的代码场景就能看懂。

什么时候需要类型守卫?

假设你是个做宠物用品店系统的程序员,要写一个“计算宠物零食运费”的小功能。宠物有两种:会飞的鹦鹉(Parrot)和会跑的狗(Dog),它们的属性不一样:鹦鹉有“ wingSpan(翼展)”,狗有“ legLength(腿长)”。如果直接写代码,你可能会这么写:

TypeScript in 类型守卫怎么用

`typescript

function getShippingFee(pet: Parrot | Dog) {

// 直接访问 wingSpan 会报错,因为狗没有这个属性

return pet.wingSpan > 50 ? 10 : 5;

}

`

这时候 TS 会给你红色波浪线,说“pet 可能是 Dog,Dog 没有 wingSpan”——就像你给狗量翼展,根本量不出来,这时候类型守卫就派上用场了:它能告诉你“这只宠物到底是鹦鹉还是狗”,让 TS 放心让你访问对应的属性。

最常用的类型守卫:typeof 判断

typeof 是 JS 自带的判断类型的方法,用在 TS 里也特别顺手,适合处理基础数据类型(比如 number、string、boolean)。

还是拿宠物店举例子,如果我们要处理的是宠物的“年龄”——有的是数字(比如 2),有的是字符串(比如“3岁”),要统一转成数字计算运费,就可以用 typeof 守卫:

`typescript

function getAgeNumber(age: number | string) {

if (typeof age === 'number') {

// 这里 TS 自动把 age 收窄成 number 类型,直接用

return age;

} else {

// 这里 TS 自动把 age 收窄成 string 类型,用 toString() 转成数字

return parseInt(age);

}

}

`

就像你收到一个“年龄”的信息,先看它是数字还是字符串:如果是数字,直接用;如果是带“岁”的字符串,就把“岁”去掉转成数字,完全不会出错。

处理对象类型的守卫:in 关键字

如果要判断两个对象里有没有某个属性,用 in 关键字最合适,比如之前的鹦鹉和狗,我们可以用 in 来区分:

`typescript

interface Parrot {

name: string;

wingSpan: number;

}

interface Dog {

name: string;

legLength: number;

}

function getPetSize(pet: Parrot | Dog) {

if ('wingSpan' in pet) {

// TS 知道这里 pet 是 Parrot,访问 wingSpan 没问题

return 这只鹦鹉的翼展是 ${pet.wingSpan} cm;

} else {

// TS 知道这里 pet 是 Dog,访问 legLength 没问题

return 这只狗的腿长是 ${pet.legLength} cm;

}

}

`

这就像你给宠物做体检,先摸它有没有翅膀(对应“wingSpan”属性),有就是鹦鹉,没有就是狗,不会搞混。

进阶用法:自定义类型守卫

如果遇到更复杂的场景,比如要判断宠物是不是“需要托运的大型宠物”,可以自己写个函数当守卫,专门判断类型。比如我们想把“体重超过 10kg 的宠物”归为一类,就可以写:

`typescript

function isHeavyPet(pet: Parrot | Dog, weight: number): pet is Parrot | Dog {

return weight > 10;

}

// 调用时用它做守卫

function checkShipping(pet: Parrot | Dog, weight: number) {

if (isHeavyPet(pet, weight)) {

return '需要走货运,运费 50 元';

} else {

return '普通快递,运费 10 元';

}

}

`

这个函数最后返回的类型是 pet is Parrot | Dog,就是告诉 TS“如果这个函数返回 true,那这个 pet 就是后面的类型”——相当于你自己给 TS 当“宠物分类员”,把复杂的判断逻辑封装成一个小工具,代码更整洁。

其实类型守卫的核心就是“收窄类型范围”,就像你整理快递包裹时,先把不同地址的包裹分开,再分别处理,既能避免搞错,又能让代码更安全。不用记复杂的术语,只要记住:遇到“可能是多种类型的变量”,用 typeof 查基础类型,用 in 查对象属性,需要自定义规则就写个带返回类型的函数,就能轻松解决大部分问题。

上一篇 C / C++编程基础入门:从语法规则到程序调试的核心知识科普