它们是我的运行时校验秘笈。不仅是类型守卫(type guard),更是告诉 TS “相信我”。在复杂校验逻辑中尤其好用。

示例:

function assertIsString(value: unknown): asserts value is string {
  if (typeof value !== 'string') throw new Error('Not a string');
}

function processInput(input: unknown) {
  assertIsString(input);
  console.log(input.toUpperCase());// ✅ TS 现在知道 input 是 string 了
}

processInput('Amit');// ✅ 成功
processInput(123);// ❌ 抛错

凡是你需要“类型把关 + 失败就中断”的地方,都可以用断言函数。

类型谓词 与 断言函数

在 TS 里“收窄类型”有时像猜谜。类型谓词value is Type)和断言函数让它精确可控

断言函数更进一步:抛错强制类型成立。两者配合,会显著提升 TS 的收窄表现,是复杂分支里的好队友

interface User {
  name: string;
}

function isUser(value: unknown): value is User {
  return typeof value === 'object' && value !== null && 'name' in value;
}

function greet(value: unknown) {
  if (isUser(value)) {
    console.log(`Hello, ${value.name}`);
  }
}

greet('Amit');// (不输出)
greet({ name: 'Amit' });// Hello, Amit

类也能很优雅

不仅仅是 OOP 爱好者的玩具——它们非常适合构建器(builder)模式,还能配合断言打造流式、类型安全的 API(例如 tRPC 的一些设计思路)。

class Client {
  private user?: { id: string };

  constructor(user?: { id: string }) {
    this.user = user;
  }

// 断言:调用后,this 必须具备 { user: { id: string } }
  assertLoggedIn(): asserts this is this & { user: { id: string } } {
    if (!this.user) throw new Error('Not logged in');
  }
}

这样可以在方法链中保证状态,写出既顺滑又安全的接口。