typescript 中自定义类型守卫函数通过 val is type 类型谓词实现在运行时判断类型并让编译器缩小类型范围;需满足单参数且返回类型为类型谓词,仅在直接调用时生效。

在 TypeScript 中,自定义类型守卫函数用于运行时判断某个值是否属于特定类型,并让编译器据此缩小类型范围。核心是函数返回类型为 val is Type 的类型谓词(type predicate)。
定义类型守卫函数
类型守卫函数必须满足两个条件:一是接收一个参数,二是返回类型形如 arg is SomeType。这个返回类型告诉 TypeScript:若函数返回 true,则该参数在后续作用域中可被安全地视为 SomeType。
例如,判断一个值是否为非空字符串:
function isNonEmptyString(val: unknown): val is string {
return typeof val === 'string' && val.length > 0;
}
注意:val is string 不是布尔类型,而是类型谓词;它不改变运行时行为,只影响类型检查。
在条件分支中使用类型守卫
调用类型守卫后,TypeScript 会在 if 块内自动收窄类型,无需额外断言或类型转换。
- 守卫返回
true时,参数类型被精确推导为谓词右侧的类型 - 守卫返回
false时,类型不会被收窄(但可用else处理其他情况)
示例:
function processInput(input: unknown) {
if (isNonEmptyString(input)) {
// 此处 input 的类型已被推导为 string(且非空)
console.log(input.toUpperCase()); // ✅ 安全调用
} else {
// input 类型仍是 unknown
console.log('Not a non-empty string');
}
}
处理联合类型与对象类型守卫
类型守卫对联合类型特别有用。比如区分接口的不同实现:
interface Admin { role: 'admin'; permissions: string[]; }
interface User { role: 'user'; lastLogin: Date; }
type Person = Admin | User;
function isAdmin(person: Person): person is Admin {
return person.role === 'admin';
}
function handlePerson(person: Person) {
if (isAdmin(person)) {
console.log(person.permissions); // ✅ 可访问 Admin 特有属性
} else {
console.log(person.lastLogin); // ✅ 此时 person 是 User
}
}
关键点:守卫函数内部逻辑需足够可靠(如检查不可变字段、类型标识符),避免误判导致类型错误。
注意事项与常见陷阱
类型守卫仅在直接调用位置生效,不能通过变量间接调用:
- ✅ 正确:
if (isNonEmptyString(x)) { ... } - ❌ 错误:
const guard = isNonEmptyString; if (guard(x)) { ... }(TypeScript 无法识别该变量是类型守卫)
另外,类型守卫不能用于泛型参数的运行时检查(因泛型擦除),需配合具体类型或 typeof/instanceof 等原生机制。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











