TypeScript 类型保护

首页 / TypeScript入门教程 / TypeScript 类型保护

在本教程中,你将学习 TypeScript 中的类型保护。

使用 条件代码块 限定变量类型的范围,达到类型保护的目的。

typeof

看看下面的例子:

type alphanumeric = string | number;

function add(a: alphanumeric, b: alphanumeric) {
  if (typeof a === 'number' && typeof b === 'number') {
    return a + b;
  }

  if (typeof a === 'string' && typeof b === 'string') {
    return a.concat(b);
  }

  throw new Error(
    'Invalid arguments. Both arguments must be either numbers or strings.',
  );
}

它是这样工作的:

在这个例子中,TypeScript 知道如何在条件代码块中使用 typeof 操作符。

在下面的 if 语句中,TypeScript 认为 ab 变量都是数字类型:

if (typeof a === 'number' && typeof b === 'number') {
  return a + b;
}

类似地,在下面的 if 语句中,TypeScript 将 ab 变量作为字符串来处理,因此,可以把它们拼接成一个字符串:

if (typeof a === 'string' && typeof b === 'string') {
  return a.concat(b);
}

instanceof

typeof 操作符类似,TypeScript 也知道如何使用 instanceof 操作符,如下所示:

class Customer {
  isCreditAllowed(): boolean {
    // ...
    return true;
  }
}

class Supplier {
  isInShortList(): boolean {
    // ...
    return true;
  }
}

type BusinessPartner = Customer | Supplier;

function signContract(partner: BusinessPartner): string {
  let message: string;
  if (partner instanceof Customer) {
    message = partner.isCreditAllowed()
      ? 'Sign a new contract with the customer'
      : 'Credit issue';
  }

  if (partner instanceof Supplier) {
    message = partner.isInShortList()
      ? 'Sign a new contract the supplier'
      : 'Need to evaluate further';
  }

  return message;
}

它这样何工作的:

  • 首先,声明了 CustomerSupplier 两个类;
  • 第二, 创建类型别名为 BusinessPartner 的类型,它是CustomerSupplier 的联合类型;
  • 第三,定义 signContract() 函数,它接受一个类型为 BusinessPartner 的参数;
  • 最后,检查 partner 是否为 Customer 或者 Supplier 类的实例,然后进行对应的逻辑处理。

在下面的 if 代码块中,TypeScript 通过 instanceof 操作符知道 partnerCustomer 类型的一个实例:

if (partner instanceof Customer) {
  message = partner.isCreditAllowed()
    ? 'Sign a new contract with the customer'
    : 'Credit issue';
}

同样的方式,在下面的 if 代码块中,TypeScript 知道 partnerSupplier 类型的一个实例:

if (partner instanceof Supplier) {
  message = partner.isInShortList()
    ? 'Sign a new contract with the supplier'
    : 'Need to evaluate further';
}

if 语句限定了一种类型,TypeScript 知道在 else 语句中会是另外一种类型,如下所示:

function signContract(partner: BusinessPartner): string {
  let message: string;
  if (partner instanceof Customer) {
    message = partner.isCreditAllowed()
      ? 'Sign a new contract with the customer'
      : 'Credit issue';
  } else {
    // must be Supplier
    message = partner.isInShortList()
      ? 'Sign a new contract with the supplier'
      : 'Need to evaluate further';
  }
  return message;
}

in

in 操作符通过判断对象上是否存在某个属性来进行安全检查,也可以将它用作类型保护,如下所示:

function signContract(partner: BusinessPartner): string {
  let message: string;
  if ('isCreditAllowed' in partner) {
    message = partner.isCreditAllowed()
      ? 'Sign a new contract with the customer'
      : 'Credit issue';
  } else {
    // must be Supplier
    message = partner.isInShortList()
      ? 'Sign a new contract the supplier '
      : 'Need to evaluate further';
  }
  return message;
}

用户自定义的类型保护

用户自定义的类型保护允许你使用函数的时候定义类型保护或者帮助 TypeScript 推断类型。用户自定义的类型保护函数是一个返回 arg is aType 判断的函数,如下所示:

function isCustomer(partner: any): partner is Customer {
  return partner instanceof Customer;
}

在这个例子中,isCustomer() 是一个用户自定义的类型保护函数,可以按照下面的例子来使用它:

function signContract(partner: BusinessPartner): string {
  let message: string;
  if (isCustomer(partner)) {
    message = partner.isCreditAllowed()
      ? 'Sign a new contract with the customer'
      : 'Credit issue';
  } else {
    message = partner.isInShortList()
      ? 'Sign a new contract with the supplier'
      : 'Need to evaluate further';
  }

  return message;
}

小结

  • 类型保护限定了条件语句中变量的类型;
  • 使用 typeofinstanceof 操作符在条件语句中实现类型保护。

教程来源:网道(WangDoc.com)以及 Github cody1991 无私奉献

这一章《TypeScript 类型保护 》你学到了什么?做站不易,你的分享是对我们最大的支持,感谢!😊

猜你喜欢

Service Mesh实践指南 -〔周晶〕

小马哥讲Spring AOP编程思想 -〔小马哥〕

如何落地业务建模 -〔徐昊〕

手把手带你搭建秒杀系统 -〔佘志东〕

好记忆不如烂笔头。留下你的足迹吧 :)