在 TypeScript 中,pet is Fish 是一种类型谓词(Type Predicate)。类型谓词是一种特殊的返回类型注解,用于在运行时告诉编译器某个变量的具体类型。这种机制通常用于自定义类型保护函数(Custom Type Guard Functions),以便在条件分支中安全地使用特定类型的特性。

解释

让我们详细解析一下这个例子:

function isFish(pet: Bird | Fish): pet is Fish {
  return (pet as Fish).swim !== undefined;
}

1. 函数签名

  • 参数: pet: Bird | Fish

    • 表示 pet 参数可以是 Bird 类型或 Fish 类型。
  • 返回类型: pet is Fish

    • 这是一个类型谓词,表示如果函数返回 true,那么 pet 必须是 Fish 类型。

2. 函数体

  • 类型断言: (pet as Fish).swim !== undefined
    • 使用类型断言将 pet 视为 Fish 类型,然后检查 swim 方法是否存在。
    • 如果 swim 方法存在,则返回 true,否则返回 false

类型谓词的作用

类型谓词 pet is Fish 的作用是在调用 isFish 函数的地方,如果函数返回 true,TypeScript 编译器会认为 pet 的类型是 Fish。这样,在后续的代码块中,你可以安全地使用 Fish 类型特有的属性和方法,而不需要额外的类型断言。

示例

interface Bird {
  fly(): void;
  layEggs(): void;
}

interface Fish {
  swim(): void;
  layEggs(): void;
}

function isFish(pet: Bird | Fish): pet is Fish {
  return (pet as Fish).swim !== undefined;
}

function move(pet: Bird | Fish) {
  if (isFish(pet)) {
    // 在这里,TypeScript 认为 pet 是 Fish 类型
    pet.swim(); // 可以安全地调用 swim 方法
  } else {
    // 在这里,TypeScript 认为 pet 是 Bird 类型
    pet.fly(); // 可以安全地调用 fly 方法
  }
}

在这个示例中,move 函数内部使用了 isFish 函数来进行类型判断。一旦 isFish 返回 true,TypeScript 就会在 if 分支内将 pet 视为 Fish 类型,从而允许调用 swim 方法。反之,在 else 分支内,pet 被视为 Bird 类型,因此可以调用 fly 方法。

总结

  • 类型谓词 (pet is Fish): 用于在自定义类型保护函数中明确告知编译器某个变量的具体类型。
  • 作用: 在类型保护函数返回 true 时,编译器会信任该函数的判断结果,并相应地调整变量的类型。
  • 好处: 提高代码的安全性和可读性,减少类型错误。