跳到主要内容

asserts关键字

asserts 是 TypeScript 中的一种断言函数类型保护机制。它用于声明一个函数会在某些条件下抛出错误,或者会改变 TypeScript 的类型推断。

基本语法

function assert(condition: any, msg?: string): asserts condition {
if (!condition) {
throw new Error(msg);
}
}

主要用途

1. 条件断言

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

let value: unknown = 'hello';
assertIsString(value);
// 这里 TypeScript 知道 value 是 string 类型
console.log(value.toUpperCase()); // ✅ 安全

2. 无条件断言

function assertNever(value: never): asserts value {
throw new Error(`Unexpected value: ${value}`);
}

function handleShape(shape: Circle | Square) {
switch (shape.kind) {
case 'circle':
return shape.radius;
case 'square':
return shape.sideLength;
default:
assertNever(shape); // 如果 shape 不是 never,会抛出错误
}
}

3. 简单的真值检查

function assert(condition: any, msg?: string): asserts condition {
if (!condition) {
throw new Error(msg || 'Assertion failed');
}
}

let value: string | null = getValue();
assert(value !== null);
// 这里 TypeScript 知道 value 不是 null
console.log(value.length); // ✅ 安全

与普通类型保护的区别

普通类型保护:返回 boolean

function isString(value: unknown): value is string {
return typeof value === 'string';
}

if (isString(value)) {
// 在这个块内 value 是 string
}

断言函数:不返回,直接改变类型

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

assertIsString(value);
// 从这里开始 value 就是 string

实际应用场景

验证 API 响应

interface User {
id: number;
name: string;
}

function assertIsUser(data: unknown): asserts data is User {
if (typeof data !== 'object' || data === null) {
throw new Error('Invalid user data');
}
if (!('id' in data) || !('name' in data)) {
throw new Error('Missing required fields');
}
}

async function fetchUser() {
const response = await fetch('/api/user');
const data = await response.json();
assertIsUser(data); // 如果无效会抛出错误
return data; // data 现在是 User 类型
}

配置验证

interface Config {
port: number;
host: string;
}

function assertValidConfig(config: unknown): asserts config is Config {
// 复杂的验证逻辑...
}

注意事项

  1. 断言函数必须抛出错误,不能正常返回如果断言失败
  2. 没有返回值(或者返回 never
  3. 在运行时确实会执行,不只是类型检查

asserts 关键字让 TypeScript 的类型系统能够理解你的断言逻辑,提供更好的类型安全性。