浅谈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高级程序设计 读书笔记之十一 内置对象Global
Mar 07 Javascript
为JS扩展Array.prototype.indexOf引发的问题探讨及解决
Apr 24 Javascript
jQuery实现图片放大预览实现原理及代码
Sep 12 Javascript
jQuery实现鼠标经过时出现隐藏层文字链接的方法
Oct 12 Javascript
js实现的星星评分功能函数
Dec 09 Javascript
深入理解JavaScript中的call、apply、bind方法的区别
May 30 Javascript
jquery实现输入框实时输入触发事件代码
Dec 21 Javascript
原生js实现鼠标跟随效果
Feb 28 Javascript
javascript回调函数的概念理解与用法分析
May 27 Javascript
解决linux下node.js全局模块找不到的问题
May 15 Javascript
vue前端框架—Mint UI详解(更适用于移动端)
Apr 30 Javascript
vue 数字翻牌器动态加载数据
Apr 20 Vue.js
原生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
一个SQL管理员的web接口
2006/10/09 PHP
php HtmlReplace输入过滤安全函数
2010/07/03 PHP
探讨php中header的用法详解
2013/06/07 PHP
LINUX下PHP程序实现WORD文件转化为PDF文件的方法
2016/05/13 PHP
PHP命名空间namespace及use的简单用法分析
2018/08/03 PHP
TP5框架实现自定义分页样式的方法示例
2020/04/05 PHP
通过PHP实现用户注册后邮箱验证激活
2020/11/10 PHP
使Ext的Template可以解析二层的json数据的方法
2007/12/22 Javascript
jQuery 点击图片跳转上一张或下一张功能的实现代码
2010/03/12 Javascript
javascript nextSibling 与 getNextElement(node) 使用介绍
2011/10/13 Javascript
javascript进行数组追加方法小结
2014/06/16 Javascript
d3.js实现自定义多y轴折线图的示例代码
2018/05/30 Javascript
用npm安装vue和vue-cli,并使用webpack创建项目的方法
2018/09/28 Javascript
JS 音频可视化插件Wavesurfer.js的使用教程
2018/10/31 Javascript
微信小程序配置服务器提示验证token失败的解决方法
2019/04/03 Javascript
javascript面向对象三大特征之继承实例详解
2019/07/24 Javascript
node.js如何根据URL返回指定的图片详解
2020/10/21 Javascript
学习 Vue.js 遇到的那些坑
2021/02/02 Vue.js
Python使用scrapy抓取网站sitemap信息的方法
2015/04/08 Python
python实现八大排序算法(2)
2017/09/14 Python
TensorFlow损失函数专题详解
2018/04/26 Python
python中的decorator的作用详解
2018/07/26 Python
Python常见的pandas用法demo示例
2019/03/16 Python
Django 使用easy_thumbnails压缩上传的图片方法
2019/07/26 Python
python:批量统计xml中各类目标的数量案例
2020/03/10 Python
PyTorch: Softmax多分类实战操作
2020/07/07 Python
利用Python如何画一颗心、小人发射爱心
2021/02/21 Python
TripAdvisor瑞典:全球领先的旅游网站
2017/12/11 全球购物
俄罗斯园林植物网上商店:Garshinka
2020/07/16 全球购物
会计出纳岗位职责
2013/12/25 职场文书
简单英文演讲稿
2014/01/01 职场文书
社区端午节活动方案
2014/01/28 职场文书
竞选劳动委员演讲稿
2014/04/28 职场文书
出国签证在职证明
2014/09/20 职场文书
小学运动会加油稿
2015/07/22 职场文书
高中化学教学反思
2016/02/22 职场文书