TypeScript类型操作补充:断言、可选链与字面量类型详解

作者:闭包旅人

时间:2026-10-25

浏览:223

本文补充TypeScript类型操作的高级用法,涵盖类型断言、非空断言、可选链操作符及字面量类型。详细解析如何处理DOM元素类型、解决编译期报错、利用??和!!操作符,以及通过字面量类型约束对象属性,提升代码安全性与开发效率。

文章目录

类型操作的补充

类型断言的使用

在TypeScript开发中,有时编译器无法推断出确切的类型信息,此时需要借助类型断言(Type Assertions)来明确指定变量的类型。

以操作DOM为例,使用 document.getElementById 获取元素时,TypeScript默认只知道返回的是 HTMLElement 类型,无法直接识别其具体是 img 还是 div 等特定元素类型。

类型操作的补充

通过添加类型断言,TypeScript 编译器能够获知具体的类型信息,从而允许进行更具体的属性访问或方法调用。

const el = document.getElementById("app") as HTMLImageElement

el.src = "图片地址"

类型操作的补充

TypeScript 严格限制类型断言的目标类型必须比源类型更具体,或者转换为 any 和 unknown 这两种宽泛类型。这一规则旨在防止发生不可能或危险的强制转换。

如果尝试将类型直接转换为不兼容的具体类型,编译器会直接报错。

类型操作的补充

虽然可以先将变量转换为 any 或 unknown,再进一步转换为目标类型(如 number),但这种做法绕过了类型检查,不推荐在实际开发中使用。

const message = "Hello World"
const num: number = (message as any) as number

非空类型的断言

在编写如下代码时,TypeScript 编译阶段会抛出错误。

这是因为传入的 message 参数可能是 undefined 类型,直接调用其方法会导致运行时错误,因此编译器禁止此类操作。

// 参数为可选类型的时候
function printMessage(message?: string) {
  console.log(message.toUpperCase())
}

printMessage("aaa")

尽管开发者确定传入的参数必然存在值,但编译器仍无法通过静态检查。此时,可以使用非空类型断言来解决编译报错问题。

非空断言使用 ! 后缀,表示开发者确定该标识符在运行时一定有值,从而跳过 TypeScript 编译阶段的空值检查。尽管这能绕过编译错误,但代码在逻辑上仍可能不够严谨,需确保运行时安全。

function printMessage(message?: string) {
  // 加上 ! 代表着保证这个message一定是有值的
  console.log(message!.toUpperCase())
}

printMessage("aaa")

可选链使用介绍

可选链并非 TypeScript 独有特性,它是 ES11( ES2020) 标准中引入的语言特性。

可选链通过操作符 ?. 实现。

其作用在于:当访问的对象属性不存在时,表达式会短路并直接返回 undefined,后续代码不再执行;若属性存在,则继续执行后续操作。

虽然可选链是 ECMAScript 标准的一部分,但在 TypeScript 中结合使用能获得更好的类型推断支持。

例如,定义如下一个对象。

type Person = {
  name: string
  friend?: {
    name: string
    age?: number
  }
}

const info: Person = {
  name: "chenyq"
}

在访问该对象属性时,name 属性保证存在,而 friend 属性可能为 undefined。

console.log(info.name)
// 表示friend有值的情况下再取name或者age, 没有值就是undefined, 代码不会报错
console.log(info.friend?.name)
console.log(info.friend?.age)

两个特殊操作符

开发者有时还会遇到 !! 和 ?? 操作符,这些符号的具体用途如下。

!! 和 ?? 操作符本质上是 JavaScript 语言特性,并非 TypeScript 特有的语法。

!!操作符:

用于将其他类型转换为 boolean 类型。

其效果类似于调用 Boolean(变量) 函数。

例如,若要将 message 转换为 boolean 类型并赋值给 flag,有两种实现方式。

const message = "Hello World"

// 方式一: 通过Boolean(变量)的方式
let flag1 = Boolean(message)
console.log(flag1) // true

// 方式二: 通过 !! 操作符
let flag2 = !!message 
console.log(flag2)

??操作符:

这是 ES11 引入的新特性。

空值合并操作符(??)是一个逻辑运算符,当左侧操作数为 null 或 undefined 时,返回右侧操作数;否则返回左侧操作数。

let message: string|null = null

// 当message没有值时, 将??操作符右边的默认值赋值给content
// 当message有值时, 将message的值赋值给content
const content = message ?? "我是默认值"
console.log(content) // 我是默认值

字面量类型介绍

除了常规类型外,TypeScript 还支持字面量类型(literal types)。

使用字面量类型时,变量的值必须与其声明的字面量完全一致。

// "Hello World"是可以作为类型的, 这个就叫字面量类型
let message: "Hello World" = "Hello World"
let num: 123 = 123

// 不能是其他的值
// message = "Hello"

这样做有什么意义呢?

单独使用字面量类型看似没有实际意义。

然而,当多个字面量类型结合联合类型使用时,就能发挥重要作用,用于限制变量只能取特定值。

// 例如我们用一个变量来保存对齐方式
let align: "left" | "right" | "center" = "left"

align = "right"
align = "center"

字面量推理介绍

观察下面的代码。

类型操作的补充

在对象进行字面量推理时,options 实际上被推断为 {url: string, method: string} 类型。由于 request 方法的参数期望的是字面量类型 Method,而 string 类型无法直接赋值给字面量类型,因此编译阶段会报错。

方式一:当我们确定 options 对象的 method 属性值无误时,可以使用类型断言(将宽泛的 string 类型断言为具体的字面量类型),如下所示。

// 使用类型断言
request(options.url, options.methods as Method)

方式二:虽然写法略显特殊,但这是官方文档推荐的做法,即给对象添加 as const 修饰符。

const options = {
  url: "http://aaa.org",
  methods: "POST"
} as const 

总结

至此,关于 TypeScript 语法详解之类型操作补充的内容介绍完毕。更多相关 TypeScript 类型操作的补充内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章