1. 基本含义

断言是开发者明确告诉编译器/运行时某个值的类型或状态的行为。
意思是:”我确定这个值是什么类型,请相信我”。

2. 在 TypeScript 中的三种断言 ★★★

2.1 类型断言(Type Assertion)

// 情况1:开发者比 TypeScript 更清楚值的类型
const value: any = "hello"

// 语法1:尖括号语法
const length1 = (<string>value).length  // 告诉 TS:value 是 string

// 语法2:as 语法(更常用)
const length2 = (value as string).length  // 告诉 TS:value 是 string

2.2 非空断言(Non-null Assertion)

// 告诉 TS:这个值一定不是 null/undefined
interface User {
  name?: string
}

function greet(user: User) {
  // ❌ 错误:可能为 undefined
  // console.log(user.name.toUpperCase())

  // ✅ 非空断言:我确定 name 有值
  console.log(user.name!.toUpperCase())

  // 等价于
  if (user.name) {
    console.log(user.name.toUpperCase())
  }
}

2.3 确定赋值断言(Definite Assignment Assertion)

// 告诉 TS:这个变量会在构造函数之外初始化
class User {
  name!: string  // 我保证会在构造函数中赋值

  constructor() {
    this.initialize()
  }

  initialize() {
    this.name = "John"
  }
}

3. 在 Vue 3 模板中的断言

<template>
  <!-- 模板中也可以使用类型断言 -->
  <div v-if="user">
    <!-- 这里 user 已经被类型收窄 -->
    <span>{{ user.name }}</span>
  </div>

  <!-- 或者使用可选链 -->
  <span>{{ user?.name }}</span>
</template>

<script setup>
import { ref } from 'vue'

const user = ref<{ name: string } | null>(null)

// 在 setup 中使用断言
const userName = computed(() => {
  return user.value?.name || 'Guest'
})

// 或者在异步操作后
const loadUser = async () => {
  const data = await fetchUser()
  user.value = data as User  // 类型断言
}
</script>

4. TypeScript 的断言函数

TypeScript 3.7+ 引入了断言函数:

// 自定义断言函数
function assertIsString(value: unknown): asserts value is string {
  if (typeof value !== 'string') {
    throw new Error('Not a string!')
  }
}

// 使用
function example(value: unknown) {
  assertIsString(value)  // 如果执行到这里,value 一定是 string
  console.log(value.toUpperCase())  // 安全
}

5. 总结

断言的核心思想:开发者在特定时刻比 TypeScript 编译器更清楚某个值的类型或状态。

概念 作用时机 示例 风险
类型断言 编译时 value as string 类型错误时运行时报错
非空断言 编译时 value! 值为空时运行时报错
NonNullable 编译时 NonNullable<T> 只是类型操作,无运行时风险
类型守卫 编译时+运行时 typeof value === 'string' 安全,有运行时检查

简单比喻

  • TypeScript 编译器:严格的老师
  • 断言:学生对老师说:”老师,我确定这个答案是对的”
  • 风险:如果学生错了,考试(运行时)会不及格(报错)

谨慎使用断言,尽量配合运行时验证,确保应用的稳定性。