浅谈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 相关文章推荐
JQuery 给元素绑定click事件多次执行的解决方法
Sep 09 Javascript
jQuery EasyUI实现右键菜单变灰不可用效果
Sep 24 Javascript
针对后台列表table拖拽比较实用的jquery拖动排序
Oct 10 Javascript
Javascript 普通函数和构造函数的区别
Nov 05 Javascript
解决bootstrap下拉菜单点击立即隐藏bug的方法
Jun 13 Javascript
解决vue中使用swiper插件问题及swiper在vue中的用法
Apr 04 Javascript
Django+vue跨域问题解决的详细步骤
Jan 20 Javascript
element-ui如何防止重复提交的方法步骤
Dec 09 Javascript
js this 绑定机制深入详解
Apr 30 Javascript
从表单校验看JavaScript策略模式的使用详解
Oct 17 Javascript
详解javascript脚本何时会被执行
Feb 05 Javascript
前端框架ECharts dataset对数据可视化的高级管理
Dec 24 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
Zerg剧情介绍
2020/03/14 星际争霸
QQ互联一键登录审核不通过的解决方案
2014/09/10 PHP
ThinkPHP3.2框架自定义配置和加载用法示例
2018/06/14 PHP
jQuery.ajax 用户登录验证代码
2010/10/29 Javascript
js弹出层(jQuery插件形式附带reLoad功能)
2013/04/12 Javascript
jquery中的事件处理详细介绍
2013/06/24 Javascript
js验证整数加保留小数点的简单实例
2013/12/02 Javascript
JavaScript中匿名、命名函数的性能测试
2014/09/04 Javascript
jQuery实现可高亮显示的二级CSS菜单效果
2015/09/01 Javascript
JavaScript保留关键字汇总
2015/12/01 Javascript
7个去伪存真的JavaScript面试题
2016/01/07 Javascript
AngularJS的ng-click传参的方法
2017/06/19 Javascript
垃圾回收器的相关知识点总结
2018/05/13 Javascript
jQuery实现获取选中复选框的值实例详解
2018/06/28 jQuery
vue 点击其他区域关闭自定义div操作
2020/07/17 Javascript
Vue-cli 移动端布局和动画使用详解
2020/08/10 Javascript
各种Python库安装包下载地址与安装过程详细介绍(Windows版)
2016/11/02 Python
python的变量与赋值详细分析
2017/11/08 Python
tensorflow1.0学习之模型的保存与恢复(Saver)
2018/04/23 Python
Python实现的NN神经网络算法完整示例
2018/06/19 Python
python random从集合中随机选择元素的方法
2019/01/23 Python
python安装pywin32clipboard的操作方法
2019/01/24 Python
python版百度语音识别功能
2019/07/09 Python
opencv调整图像亮度对比度的示例代码
2019/09/27 Python
浅析Python __name__ 是什么
2020/07/07 Python
StubHub巴西:购买和出售您的门票
2016/07/22 全球购物
法国家具及室内配件店:home24
2017/01/21 全球购物
新电JAVA笔试题目
2014/08/31 面试题
如何拷贝一整个Java对象,包括它的状态
2013/12/27 面试题
酒店门卫岗位职责
2013/12/29 职场文书
中学生打架检讨书
2014/02/10 职场文书
委托公证书
2014/04/08 职场文书
入党推优材料
2014/06/02 职场文书
兽医医药专业求职信
2014/07/27 职场文书
毕业生捐书活动倡议书
2015/04/27 职场文书
2015年“我们的节日·重阳节”活动总结
2015/07/29 职场文书