Narrowing概念:字面意思是缩小,可以理解为细化或者您觉得更好的代名词。

TS官方在这里做了很详细的说明,文字较多,简单以图片概括:

typeof  type guards 类型防护过程,可以通过 typeof 检测出大部分类型并对比预设类型,如:

  • "string"
  • "number"
  • "boolean"
  • "symbol"
  • "undefined"
  • "object"
  • "function"

但是对于特殊的对象,比如 null ,typeof 就无能为力了,因为 typeof null === 'object'。看个例子:

function printAll(strs: string | string[] | null) {
  if (typeof strs === "object") {
    for (const s of strs) {   //for of 遍历数组中的元素

      //  Object is possibly 'null'.Object is possibly 'null'.

      console.log(s);
  }
  } else if (typeof strs === "string") {
    console.log(strs);
  } else {
    // do nothing
  }
}
 
布尔值运算
因为对下列这些对象进行布尔运算返回都是 false : 
  • 0
  • NaN
  • null
  • undefined
  • ""

所以上面的例子可以先对 null 进行判断然后执行后面的逻辑

function printAll(strs: string | string[] | null) {
  if (strs && typeof strs === "object") {
    for (const s of strs) {   //for of 遍历数组中的元素

      // strs 如果是null则跳过这个分支

      console.log(s);
  }
  } else if (typeof strs === "string") {
    console.log(strs);
  } 
}
 
思考以下两个方法有何不同?
 
function printAll(strs: string | string[] | null) {
  if (strs) {
    if (typeof strs === "object") {
      for (const s of strs) {
        console.log(s);
      }
    } else if (typeof strs === "string") {
      console.log(strs);
    }
  }
}
 
function anotherPrintAll(strs: string | string[] | null) {
  if (strs !== null) {
    if (typeof strs === "object") {
      for (const s of strs) {
        console.log(s);
      }
    } else if (typeof strs === "string") {
      console.log(strs);
    }
  }
}
 
  使用 in 操作符进行类型缩小
js中使用in操作符可以判单一个对象是否拥有某个属性,ts 也将in作为缩小类型判断的方式。
比如在一个联合类型中,可以这样判断 'value' in x,
x可能是 type Animal = Fish | Bird, value 表示 x 中的某一个字面量(可能是Fish或者Bird)
 
type Fish = { swim: () => void };
type Bird = { fly: () => void };
function move(animal: Fish | Bird) {
  if ("swim" in animal) {
    return animal.swim();
  }
  return animal.fly();
}
 
使用类型谓词
有时候我们希望从更多角度控制类型的检测,定义一个自定义的类型防护,即定义一个返回类型的方法就是一个类型谓词。
例如:
function isFish(pet: Fish | Bird): pet is Fish {
  return (pet as Fish).swim !== undefined;
}
pet is Fish 就是一个类型谓词。定义一个类型谓词的方式:参数名称 is 类型名称,参数名称必须是当前方法的一个参数。
任何时候,只要isFish携带参数调用了,如果原始类型兼容,TypeScript会将该变量缩小到该特定类型。
例如:
 
let pet = getSmallPet();
if(isFish(pet)) {
  pet.swim();
} else {
  pet.fly();
}
 
ts可以在if分支处得知pet是一条能游的Fish,当然了在else分支处pet被当作一只能飞的Bird。
当然了,你可以使用isFish这个类型防护去过滤一个包含了飞鸟与鱼的数组,最后得到一个尽是鱼的数组。
例如:
 
const zoo: (Fish | Bird)[] = [getSmallPet(), getSmallPet(), getSmallPet()];
const underWater: Fish[] = zoo.filter(isFish)

TypeScript 中文教程之缩小----部分翻译自TS官方的更多相关文章

  1. TYPESCRIPT中文教程基础部分下----翻译自TS官方

    type 别名 我们已经使用过 object 和 联合的方式 直接声明类型.但是某个类型在使用多次的情况下就要用到别名了. 别名的语法就像是在定义一个具名的对象一样: type Point = { x ...

  2. TypeScript中文教程基础部分上----翻译自TS官方

    为什么使用TS? js中每一个值在不同的操作运行中表现出一系列不同的行为,比如说下面这个例子: message.toLowerCase();message(); 逐行看下,第一行调用了message的 ...

  3. 【翻译】在TypeScript中,Extends和Implements一个抽象类有什么不同

    我们知道在TypeScript中一个类既可以被implement也可以被extends,有一些C#或java基础的同学可能会对此感到困惑,因为在上述两个面向对象的语言里面只有接口可以被implemen ...

  4. Intellij IDEA 2017 详细图文教程之概述

    天天编码 , 版权所有丨本文标题:Intellij IDEA 2017 详细图文教程之概述 转载请保留页面地址:http://www.tiantianbianma.com/intellij-idea- ...

  5. TypeScript Handbook 1——基本类型(翻译)

    原文出处: http://www.typescriptlang.org/Handbook 基于对web开发的需要和对安神的崇拜,打算学习一下typescript. 能力有限,基本属于在自己认识的基础上 ...

  6. 5种在TypeScript中使用的类型保护

    摘要:在本文中,回顾了TypeScript中几个最有用的类型保护,并通过几个例子来了解它们的实际应用. 本文分享自华为云社区<如何在TypeScript中使用类型保护>,作者:Ocean2 ...

  7. 【TypeScript】如何在TypeScript中使用async/await,让你的代码更像C#。

    [TypeScript]如何在TypeScript中使用async/await,让你的代码更像C#. async/await 提到这个东西,大家应该都很熟悉.最出名的可能就是C#中的,但也有其它语言也 ...

  8. TypeScript中的怪语法

    TypeScript中的怪语法 如何处理undefined 和 null undefined的含义是:一个变量没有初始化. null的含义是:一个变量的值是空. undefined 和 null 的最 ...

  9. JavaScript 和 TypeScript 中的 class

    对于一个前端开发者来说,很少用到 class ,因为在 JavaScript 中更多的是 函数式 编程,抬手就是一个 function,几乎不见 class 或 new 的踪影.所以 设计模式 也是大 ...

随机推荐

  1. Dubbo应用到web工程

    一.创建提供者03-provider-web (1) 创建工程 创建Maven的web工程,然后创建实现类. (2) 导入依赖 Spring的版本为4.3.16 需要的依赖有: dubbo2.7.0版 ...

  2. 【Linux】【Database】【MySQL】使用percona搭建高可用的MySQL数据库

    1. 简介 1.1. 官方文档: 数据库架构:https://docs.openstack.org/ha-guide/shared-database.html 1.2. 本次使用的的是Percona ...

  3. 【Service】【Web】【Middleware】Tomcat

    1. 概念 1.1. 官方网站:tomcat.apache.org 1.2. tomcat的组件 <Server> <Service> <Connector/> & ...

  4. 【Linux】【Basis】Grub

    GRUB(Boot Loader):   1. grub: GRand Unified Bootloader grub 0.x: grub legacy grub 1.x: grub2   2. gr ...

  5. mybtis入门

    1.编写持久化对象 public class User { private String id;//用户编号 private String username;//用户名 private String ...

  6. RabbitMQ,RocketMQ,Kafka 几种消息队列的对比

    常用的几款消息队列的对比 前言 RabbitMQ 优点 缺点 RocketMQ 优点 缺点 Kafka 优点 缺点 如何选择合适的消息队列 参考 常用的几款消息队列的对比 前言 消息队列的作用: 1. ...

  7. opencv学习(四)——轨迹栏作为调色板

    轨迹栏作为调色板 在这里,我们将创建一个简单的应用程序,以显示指定的颜色.有一个显示颜色的窗口,以及三个用于指定B.G.R颜色的轨迹栏.滑动轨迹栏,并相应地更改窗口颜色.默认情况下,初始颜色将设置为黑 ...

  8. Jenkins获取jar包的快照号

    目录 一.简介 二.脚本 一.简介 主要用于打jar包的工程,显示快照包的名字.当jar打包完成后,会在target目录中,截取快照名. 二.脚本 1.脚本return-version.sh #!/b ...

  9. Nginx结构原理全解析

    目录 一.Nginx简单介绍 二.Nginx优势 IO多路复用epoll模型 轻量级 Nginx的基本功能 .Nginx应用场景 Nginx代理 三.Nginx的结构解析 进程操作 事件模型 事件处理 ...

  10. Windows 10 彻底关闭 Antimalware Service Executable 降低内存占用

    概述 最近给内网的一台电脑安装 Windows 10 专业版系统,由于此电脑不会涉及到不安全因素,所以杀毒软件非必须. 以最大限度节省系统资源考虑,默认安装的 Micoroft Defender 占用 ...