它们是我的运行时校验秘笈。不仅是类型守卫(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');
}
}
这样可以在方法链中保证状态,写出既顺滑又安全的接口。