跳到主要内容

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. isas 有什么区别

这是特别高频的对比题。

  • is:通过函数返回结果让编译器收窄类型;
  • as:开发者直接断言“把它当成某种类型”。
const a = value as User;

这里不会真的校验 value 是不是 User

所以更稳的说法是:

  • is 偏“验证后收窄”;
  • as 偏“直接相信”。

5. is 的返回值为什么还是普通布尔值

因为运行时并没有“类型值”这回事。

function isNumber(value: unknown): value is number {
return typeof value === "number";
}

运行时仍然只是返回 truefalse

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 isinstanceof 的关系是什么

  • instanceof 是具体的一种运行时判断方式;
  • is 是把某个判断函数声明成“成功时能收窄为某类型”的语法。

你完全可以在 isXxx 函数里使用 instanceof

8. 常见误区

  • 误区 1:以为 is 会在运行时创建新类型。
    • 它只影响编译器的理解。
  • 误区 2:写了 value is User 就算校验完整了。
    • 如果守卫逻辑不严谨,照样可能误判。
  • 误区 3:把 isas 混为一谈。
    • 一个偏收窄,一个偏断言。

速记要点

  • is 用于自定义类型守卫。
  • 典型形态:arg is SomeType
  • 它的价值是帮助 TypeScript 在分支里收窄类型。