is 关键字的作用是什么?
下文默认基于 TypeScript 5.x,并假设开启
strict: true。
面试速答(30 秒版 TL;DR)
is主要用于类型谓词(type predicate)。- 它告诉 TypeScript:如果某个函数返回
true,那么某个值就可以被当成更具体的类型。 - 经典写法是:
function isString(value: unknown): value is string {
return typeof value === "string";
}
- 它的核心价值不是运行时产生新类型,而是帮助编译器做类型收窄。
1. 为什么需要 is
看这个例子:
function print(value: unknown) {
if (typeof value === "string") {
console.log(value.toUpperCase());
}
}
这是最基础的收窄。
但如果判断逻辑变复杂,而且要复用,直接写在 if 里就很难维护。
这时就需要自定义类型守卫:
function isString(value: unknown): value is string {
return typeof value === "string";
}
2. value is string 到底是什么意思
它的含义是:
- 这个函数返回
boolean; - 但如果返回
true,编译器就把value当成string。
使用时:
function print(value: unknown) {
if (isString(value)) {
console.log(value.toUpperCase());
}
}
这时候 if 分支里的 value 就被收窄成了 string。
3. 工程里最常见的用法:对象结构校验
type User = {
id: number;
name: string;
};
function isUser(value: unknown): value is User {
return (
typeof value === "object" &&
value !== null &&
"id" in value &&
typeof value.id === "number" &&
"name" in value &&
typeof value.name === "string"
);
}
使用:
function greet(value: unknown) {
if (isUser(value)) {
return `hello ${value.name}`;
}
return "invalid user";
}
4. is 和 as 有什么区别
这是特别高频的对比题。
is:通过函数返回结果让编译器收窄类型;as:开发者直接断言“把它当成某种类型”。
const a = value as User;
这里不会真的校验 value 是不是 User。
所以更稳的说法是:
is偏“验证后收窄”;as偏“直接相信”。
5. is 的返回值为什么还是普通布尔值
因为运行时并没有“类型值”这回事。
function isNumber(value: unknown): value is number {
return typeof value === "number";
}
运行时仍然只是返回 true 或 false。
is 的特别之处在于:
- 它把这个布尔结果和类型推导关联了起来。
6. 另一个常见写法:this is
在类里也能写类型谓词:
class FileDownloader {
private url?: string;
hasURL(): this is this & { url: string } {
return typeof this.url === "string";
}
}
虽然面试不一定深挖到这里,但提一句会显得你知道它不只限于普通函数参数。
7. 高频面试题标准答法
7.1 is 是运行时关键字吗
严格说它是 TypeScript 类型谓词语法的一部分,不是普通 JavaScript 运行时操作符。
7.2 is 能不能替代所有类型判断
不能。
它只是把你已有的判断逻辑包装成可复用的类型守卫。
7.3 is 和 instanceof 的关系是什么
instanceof是具体的一种运行时判断方式;is是把某个判断函数声明成“成功时能收窄为某类型”的语法。
你完全可以在 isXxx 函数里使用 instanceof。
8. 常见误区
- 误区 1:以为
is会在运行时创建新类型。- 它只影响编译器的理解。
- 误区 2:写了
value is User就算校验完整了。- 如果守卫逻辑不严谨,照样可能误判。
- 误区 3:把
is和as混为一谈。- 一个偏收窄,一个偏断言。
速记要点
is用于自定义类型守卫。- 典型形态:
arg is SomeType。 - 它的价值是帮助 TypeScript 在分支里收窄类型。