TypeScript类型缩小详解:掌握Type Narrowing与类型保护

作者:代码拾荒

时间:2026-10-26

浏览:436

本文深入解析TypeScript中的类型缩小(Type Narrowing)机制,介绍如何通过typeof、平等比较、instanceof及in运算符实现类型保护。通过具体代码示例,展示如何在不同执行路径中精确推断变量类型,提升代码安全性与可读性。

文章目录

类型缩小

类型缩小的概念解析

TypeScript中的类型缩小对应英文术语Type Narrowing。

开发者可以利用类似 typeof padding === "number" 的条件判断语句,来引导TypeScript编译器调整执行路径。

在特定的代码执行分支中,将变量类型限制为比原始声明更具体的子集,这一过程即被称为类型缩小。

用于触发这种缩小行为的 typeof padding === "number" 等表达式,在TypeScript中被称为类型保护(type guards)。

TypeScript中常见的类型保护机制包括以下几种:

  • typeof 运算符
  • 平等性比较(如 ===、!==)
  • instanceof 运算符
  • in 运算符
  • 以及其他扩展机制。

本文将重点讲解 typeof、平等缩小、instanceof 以及 in 这四种核心类型保护方式。

typeof 类型保护

在TypeScript中,typeof 运算符的返回值被用作类型保护,因为TypeScript内部已编码了对不同值使用 typeof 操作时的类型推断规则。

例如,封装一个接收参数 ID 的函数,该参数 ID 的类型可能是 string 或 number。

当传入的 ID 为 string 类型时,逻辑要求将 ID 的字母全部转换为大写。

function printID(id: string|number) {
  if (typeof id === "string") {
    console.log(id.toUpperCase())
  } else {
    console.log(id)
  }
}

// 测试
printID(123)
printID("aaa")
  • 在上述代码结构中,整个 if 判断语句构成了类型缩小逻辑:当代码进入 if 的第一个分支时,TypeScript 能确定变量一定是 string 类型;进入 else 分支时,则确定一定是 number 类型。
  • 这种 if 判断语句本身即被称为类型保护。

平等缩小

我们可以使用 switch 语句或相等性运算符(如 ===、!==、==、!=)来表达相等性判断,从而实现类型缩小。

type Direction = "left" | "right" | "top" | "bottom"
function printDirection(direction: Direction) {
  // 平等类型缩小
  switch (direction) {
    case "left":
      console.log(direction)
      break
    case "right":
      console.log(direction)
      break
    case "top":
      console.log(direction)
      break
    case "bottom":
      console.log(direction)
      break
    default:
      console.log("调用默认方法")
  }
}

// 测试
printDirection("left")
printDirection("right")
printDirection("top")
printDirection("bottom")

instanceof 类型保护

JavaScript 提供了一个运算符,用于检查一个值是否为另一个值的“实例”。

function printTime(time: string|Date) {
  // 判断time是否是Date的实例
  if (time instanceof Date) {
    console.log(time.toUTCString())
  } else {
    console.log(time)
  }
}

// 测试
printTime("2020-01-02")
const date = new Date()
printTime(date)

若对上述概念理解有困难,可参考以下具体示例。

class Teacher {
  working() {
    console.log("正在工作")
  }
}

class Student {
  studying() {
    console.log("正在学习")
  }
}

function work(p: Student | Teacher) {
  // 判断是哪一个实例
  if (p instanceof Teacher) {
    p.working()
  } else {
    p.studying()
  }
}

// 测试
const stu = new Student()
const tec = new Teacher()

work(stu) // 正在学习
work(tec) // 正在工作

in 类型保护

JavaScript 提供了一个 in 运算符,用于确定对象是否包含指定名称的属性。

如果指定的属性存在于指定对象或其原型链中,in 运算符将返回 true。

// () => void表示是一个函数类型
type Dog = {running: () => void}
type Fish = {swimming: () => void}

function walk(animal: Dog|Fish) {
  // 判断函数是否在animal中
  if ("swimming" in animal) {
    animal.swimming()
  } else {
    animal.running()
  }
}

// 测试
const dog: Dog = {
  running() {
    console.log("狗是跑的")
  }
}
const fish: Fish = {
  swimming() {
    console.log("鱼是游的")
  }
}

walk(dog) // 狗是跑的
walk(fish) // 鱼是游的

总结

至此,关于TypeScript类型缩小的介绍已完成。如需了解更多TypeScript类型缩小相关内容,请查阅本站往期文章或继续浏览后续相关文章,感谢大家的支持!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章