浅谈TypeScript的类型保护机制


Posted in Javascript onFebruary 23, 2020

在编写 TS 时,它做了比我们看到的更多的事情,例如类型保护机制。让我们编写的代码更加严谨,至于怎么回事,让我们来看看吧。

由于这些机制的存在,就算你仍旧以 JS 原生的书写方式,也能帮助你提前发现代码中潜在的问题。(对于认为 TS 语句更复杂的人,也能实现 0 门槛,不改变已有的习惯也能享受静态检测的好处。)

类型保护就是一些表达式,它们会在运行时检查以确保在某个作用域内的类型。

为了更简单的理解,我们首先声明一个联合类型用于举例:

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

interface Fish {
 swim(): any
 layEggs(): any
}

type Pet = Bird | Fish;

无类型保护时报错

function fn(pet: Pet) { 
 pet.layEggs(); // okay
 pet.swim();  // Error: Property 'swim' does not exist on type 'Bird | Fish'.
}

因为 TS 并不知道 pet 的实例是 Bird 还是 Fish,因此为了谨慎起见,在未手动声明类型时 TS 中只能调用 联合类型 中的 公共方法,例子中未 layEggs() 方法。除非你在调用指定对象数据的属性或方法前,明确告诉 TS 数据对象是一个具体的类型。

类型断言实现类型保护

我需要使用 <Fish>pet 的 类型断言,来告诉 TS 目标对象是什么类型:

function fn(pet: Fish | Bird) {
 if ((<Fish>pet).swim) {
  (<Fish>pet).swim();
 } else {
  (<Bird>pet).fly();
 }
}

虽然这样的断言满足了我们的需求,但并不好方便,需要在各处都进行引用。
备注:如果在编写 tsx 时,你需要将 (<Fish>pet) 写成 (pet as Fish),因为在 tsx 中尖括号 <> 有特殊的含义。

函数中使用 is 定位类型

我们将上面的 if 内的判断封装到函数中,获得更方便的类型保护方式,此函数必须使用 parameterName is Type 的 类型谓语:

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

此函数必须返回为 boolean 类型才生效,当返回 true 时则类型定位为 Fish ,返回 false 时则定位为 Fish 之外的类型(多个类型则以 联合类型 定位)。

function fn(pet: Fish | Bird ) { 
 if (isFish(pet)) {
  pet.swim(); // 因 is 语句的生效,此语句块中类型 let pet: Fish
 } else {
  pet.fly(); // 排除 Fish 之外的类型,此语句块中类型 let pet: Bird
 }
}

需要注意是除了 if 中类型生效,TS 还能自动推断出 else 中的类型。

就算你不使用 TS 这些特定的语句,也能享受 类型保护机制 的好处,下面让我们来看看。

使用 typeof 进行类型保护

如果子类型是只是 number、string、boolean、symbol 这几种数据类型,则可以直接使用 typeof 关键字,TS 能够检测并提供类型保护,我们直接引用官方给的例子:

function padLeft(value, padding): string {
  if (typeof padding === "number") {
    return Array(padding + 1).join(" ") + value;  // let padding: number
  }
  else {
    return padding + value;  // let padding: string
  }
}
  
const t1 = padLeft("world", 6);    // "   world"
const t2 = padLeft("world", "hello "); // "hello world"

使用 instanceof 进行类型保护

由于现在前端对于 面向对象 的开发项目越来越多,因此类的引用也更多了。那么类型保护用在此时,可谓是更加有重要,我们使用 instanceof 来达到这一效果:

interface IA { x(): void; }
interface IB { y(): void; }

class A implements IA {
 x() { }
}
class B implements IB {
 y() { }
}

function fn(e: A | B) {
 if (e instanceof A)
  e.x(); // let e: A
 else
  e.y(); // let e: 
}

基于类型保护机制,在语句块中编辑器会给予指定类型的 方法提示,以及类型检测时会提示用户。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript中void(0)的具体含义解释
Feb 27 Javascript
JavaScript中Object和Function的关系小结
Sep 26 Javascript
Javascript结合css实现网页换肤功能
Nov 02 Javascript
javascript数组的使用
Mar 28 Javascript
判断js对象是否拥有某一个属性的js代码
Aug 16 Javascript
js实现图片无缝滚动特效
Mar 19 Javascript
JS获取IMG图片高宽的简单实例
May 17 Javascript
vue.js组件之间传递数据的方法
Jul 10 Javascript
学习jQuery中的noConflict()用法
Sep 28 jQuery
js实现unicode码字符串与utf8字节数据互转详解
Mar 21 Javascript
JS中比较两个Object数组是否相等方法实例
Nov 11 Javascript
如何用Node.js编写内存效率高的应用程序
Apr 30 Javascript
原生javascript制作的拼图游戏实现方法详解
Feb 23 #Javascript
原生javascript运动函数的封装示例【匀速、抛物线、多属性的运动等】
Feb 23 #Javascript
es6中Promise 对象基本功能与用法实例分析
Feb 23 #Javascript
原生JavaScript之es6中Class的用法分析
Feb 23 #Javascript
原生javascript单例模式的应用实例分析
Feb 23 #Javascript
小程序websocket心跳库(websocket-heartbeat-miniprogram)
Feb 23 #Javascript
webpack.DefinePlugin与cross-env区别详解
Feb 23 #Javascript
You might like
一个简洁的多级别论坛
2006/10/09 PHP
php面向对象全攻略 (十七) 自动加载类
2009/09/30 PHP
将一维或多维的数组连接成一个字符串的php代码
2010/08/08 PHP
javascript 流畅动画实现原理
2009/09/08 Javascript
百度留言本js 大家可以参考下
2009/10/13 Javascript
10款新鲜出炉的 jQuery 插件(Ajax 插件,有幻灯片、图片画廊、菜单等)
2011/06/08 Javascript
JavaScript中使用typeof运算符需要注意的几个坑
2014/11/08 Javascript
jquery自定义表格样式
2015/11/23 Javascript
Bootstrap布局组件教程之Bootstrap下拉菜单
2016/06/12 Javascript
各式各样的导航条效果css3结合jquery代码实现
2016/09/17 Javascript
AngularJS入门教程之过滤器用法示例
2016/11/02 Javascript
详解使用vue-cli脚手架初始化Vue项目下的项目结构
2018/03/08 Javascript
JS简单获取并修改input文本框内容的方法示例
2018/04/08 Javascript
微信小程序之批量上传并压缩图片的实例代码
2018/07/05 Javascript
vue代理和跨域问题的解决
2018/07/18 Javascript
react实现移动端下拉菜单的示例代码
2020/01/16 Javascript
[40:55]Liquid vs LGD 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
python中xrange和range的区别
2014/05/13 Python
Python复制文件操作实例详解
2015/11/10 Python
Python走楼梯问题解决方法示例
2018/07/25 Python
对PyTorch torch.stack的实例讲解
2018/07/30 Python
python使用Matplotlib绘制分段函数
2018/09/25 Python
Python迭代器模块itertools使用原理解析
2019/12/11 Python
django下创建多个app并设置urls方法
2020/08/02 Python
深入了解Python 方法之类方法 &amp; 静态方法
2020/08/17 Python
Python爬虫教程之利用正则表达式匹配网页内容
2020/12/08 Python
DJI美国:消费类无人机领域的领导者
2018/04/27 全球购物
SCHIESSER荷兰官方网站:德国内衣专家
2020/10/09 全球购物
酒店办公室文员岗位职责
2013/12/18 职场文书
幼儿园优秀教师事迹
2014/02/13 职场文书
城管执法人员纪律作风整顿思想汇报
2014/09/13 职场文书
店铺转让协议书
2014/12/02 职场文书
2014年办公室文秘工作总结
2014/12/09 职场文书
2015年服务员个人工作总结
2015/05/27 职场文书
如何解决springcloud feign 首次调用100%失败的问题
2021/06/23 Java/Android
Win11 引入 Windows 365 云操作系统,适应疫情期间混合办公模式:启动时直接登录、模
2022/04/06 数码科技