【问题标题】:Alternative ways to use User-defined type guards?使用用户定义类型保护的替代方法?
【发布时间】:2017-06-27 08:00:04
【问题描述】:

我正在阅读 Typescript 手册中有关用户定义类型保护的内容。假设您有一个想要缩小范围的联合类型,如下所示:

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

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

class SmallPet implements Fish,Bird{
    constructor(){
    }
    fly() { console.log("fly")};
    swim() { console.log("swim")};
    layEggs() {console.log("laying eggs") };
}

function getSmallPet(): Fish | Bird{
    return new SmallPet();
}

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

let pet = getSmallPet();

if (isFish(pet))
    pet.swim(); //works

函数 isFish 是手册中提到的用户定义的类型保护。我的问题是这是如何工作的?我试图以更草率的方式实现相同的结果,但这显然不会奏效:

pet is Fish;
pet.swim(); //doesn't work

Typescript 是否必须解析一个看起来像类型保护的函数才能实现此功能并随后通过函数调用缩小类型?没有其他方法可以使用类型保护吗?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    guide

    类型保护是一些执行运行时检查的表达式,以保证某个范围内的类型。

    所以当你使用类型保护时,类型检查器会缩小当前范围的实例类型:在这种情况下是 if 块

    在 if 语句中使用 pet instanceof Fish 可以完成相同的操作。类型检查器对当前范围进行相同类型的缩小。

    【讨论】:

      【解决方案2】:

      用户定义的类型保护有两个功能:

      1. 在运行时检查一个值是否属于某种类型
      2. 告诉编译器一个值属于某种类型

      如果您知道您的实例是Fish 类型,那么您可以简单地:

      (pet as Fish).swim();
      

      在您的情况下,您还可以使用 instanceof 类型保护:

      if (pet instanceof SmallPet) {
          pet.swim();
      }
      

      【讨论】:

        猜你喜欢
        • 2018-03-26
        • 2015-12-19
        • 1970-01-01
        • 2019-01-03
        • 2021-10-31
        • 2016-09-06
        • 2018-05-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多