is
是 TypeScript 中的一个特殊关键字,用于类型谓词(Type Predicates),它允许你在自定义类型守卫函数中明确指定变量的类型。
一、基本语法
function isType(value: any): value is Type {
// 返回布尔值
}
二、核心作用
-
在函数中明确类型收缩:告诉 TypeScript 编译器,如果函数返回
true
,则参数一定是特定类型 -
增强类型推断:使自定义类型检查函数能够像
typeof
或instanceof
一样影响类型推断
三、使用示例
1、基础示例
function isString(value: unknown): value is string {
return typeof value === 'string';
}
const test: unknown = "hello";
if (isString(test)) {
// 在此块中,TypeScript 知道 test 是 string 类型
console.log(test.toUpperCase()); // 安全调用
}
2、更复杂的类型判断
interface Cat {
meow(): void;
}
interface Dog {
bark(): void;
}
function isCat(animal: Cat | Dog): animal is Cat {
return 'meow' in animal;
}
function handleAnimal(animal: Cat | Dog) {
if (isCat(animal)) {
animal.meow(); // 确定是 Cat
} else {
animal.bark(); // 确定是 Dog
}
}
3、与泛型结合使用
function isDefined<T>(value: T | undefined | null): value is T {
return value !== undefined && value !== null;
}
const maybeString: string | undefined = /* ... */;
if (isDefined(maybeString)) {
// maybeString 现在被推断为 string
console.log(maybeString.length);
}
四、与普通布尔返回函数的区别
普通布尔返回函数不会影响类型推断:
function isStringSimple(value: unknown): boolean {
return typeof value === 'string';
}
const test: unknown = "hello";
if (isStringSimple(test)) {
// 这里 test 仍然是 unknown 类型
console.log(test.toUpperCase()); // 错误!
}
而使用 is
的类型谓词函数会改变类型推断:
function isStringTypePredicate(value: unknown): value is string {
return typeof value === 'string';
}
if (isStringTypePredicate(test)) {
// 这里 test 是 string 类型
console.log(test.toUpperCase()); // 正确!
}
五、实际应用场景
1、数据验证
function isValidUser(user: any): user is { name: string; age: number } {
return user && typeof user.name === 'string' && typeof user.age === 'number';
}
2、API响应处理
function isApiSuccess(response: any): response is { data: T, status: 200 } {
return response.status === 200 && 'data' in response;
}
3、类型区分
type Square = { kind: 'square'; size: number };
type Circle = { kind: 'circle'; radius: number };
function isSquare(shape: Square | Circle): shape is Square {
return shape.kind === 'square';
}
六、注意事项
-
必须返回布尔值:类型谓词函数必须返回
true
或false
-
运行时必须真实反映类型:类型谓词只是编译时的断言,你需要确保运行时检查确实能正确识别类型
-
不能过度使用:只在需要影响类型推断的地方使用,简单的类型检查可以直接用
typeof
或instanceof