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 {
// 复杂的验证逻辑...
}
注意事项
- 断言函数必须抛出错误,不能正常返回如果断言失败
- 没有返回值(或者返回
never
) - 在运行时确实会执行,不只是类型检查
asserts
关键字让 TypeScript 的类型系统能够理解你的断言逻辑,提供更好的类型安全性。