浅谈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在一段文字中的光标处插入其他文字
Aug 26 Javascript
javascript中window.event事件用法详解
Dec 11 Javascript
批量修改标签css样式以input标签为例
Jul 31 Javascript
JavaScript获取网页、浏览器、屏幕高度和宽度汇总
Dec 18 Javascript
AngularJS整合Springmvc、Spring、Mybatis搭建开发环境
Feb 25 Javascript
实例讲解Jquery中隐藏hide、显示show、切换toggle的用法
May 13 Javascript
JS实现显示带倒影的图片横排居中放大展示特效实例【测试可用】
Aug 23 Javascript
Angular工具方法学习
Dec 26 Javascript
微信小程序实现带刻度尺滑块功能
Mar 29 Javascript
用vue封装插件并发布到npm的方法步骤
Oct 18 Javascript
vue 挂载路由到头部导航的方法
Nov 13 Javascript
element-ui 本地化使用教程详解
Oct 28 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
PHP的FTP学习(四)
2006/10/09 PHP
如何将数据从文本导入到mysql
2006/10/09 PHP
Yii框架弹出窗口组件CJuiDialog用法分析
2017/01/07 PHP
PHP按符号截取字符串的指定部分的实现方法
2018/09/10 PHP
javaScript面向对象继承方法经典实现
2013/08/20 Javascript
jquery+CSS实现的多级竖向展开树形TRee菜单效果
2015/08/24 Javascript
jQuery Ajax使用FormData对象上传文件的方法
2016/09/07 Javascript
深入理解AngularJS中的ng-bind-html指令和$sce服务
2016/09/08 Javascript
微信小程序 网络请求(GET请求)详解
2016/11/16 Javascript
JavaScript奇技淫巧44招【实用】
2016/12/11 Javascript
AngularJS基于MVC的复杂操作实例讲解
2017/12/31 Javascript
vue计算属性和监听器实例解析
2018/05/10 Javascript
Vue Router去掉url中默认的锚点#
2018/08/01 Javascript
微信小程序 MinUI组件库系列之badge徽章组件示例
2018/08/20 Javascript
微信小程序的tab选项卡的实现效果
2019/05/15 Javascript
JavaScript遍历查找数组中最大值与最小值的方法示例
2019/05/24 Javascript
vue开发拖拽进度条滑动组件
2019/09/21 Javascript
JS动态图片的实现方法完整示例
2020/01/13 Javascript
vue+vant实现购物车全选和反选功能
2020/11/17 Vue.js
vue 计算属性和侦听器的使用小结
2021/01/25 Vue.js
Python数据类型学习笔记
2016/01/13 Python
python根据url地址下载小文件的实例
2018/12/18 Python
pandas 层次化索引的实现方法
2019/07/06 Python
python中实现栈的三种方法
2020/12/19 Python
SKECHERS官方旗舰店:美国舒适运动休闲品牌
2017/12/22 全球购物
法国在线购买汽车轮胎网站:123pneus.fr
2019/02/25 全球购物
shell的种类有哪些
2015/04/15 面试题
社区安全检查制度
2014/02/03 职场文书
劳动工资科岗位职责范本
2014/03/02 职场文书
主题教育活动总结
2014/05/05 职场文书
员工合理化建议书
2014/05/19 职场文书
农业局党的群众路线教育实践活动整改方案
2014/09/20 职场文书
2014年领班工作总结
2014/11/25 职场文书
公务员个人考察材料
2014/12/23 职场文书
原生CSS实现文字无限轮播的通用方法
2021/03/30 HTML / CSS
python基础之while循环语句的使用
2021/04/20 Python