在编写 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: }
基于类型保护机制,在语句块中编辑器会给予指定类型的 方法提示,以及类型检测时会提示用户。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本节介绍的类型保护 TypeScript 类型检查机制的第二个部分,我们可以通过 typeof、instanceof、in 和 字面量类型 将代码分割成范围更小的代码块,在这一小块中,变量的类型是确定的。 1. 慕课解释 类型保护是指缩小类型的范围,在一定的块级作用域内由编译器推导其类型,提示并规避不合法的操作。 2. typeof 通过 typeof 运算符判断变量类型,下面看一个之前介绍函数重
本文向大家介绍浅谈Python中的数据类型,包括了浅谈Python中的数据类型的使用技巧和注意事项,需要的朋友参考一下 数据类型: Float/Int: 运算符: / — 浮点运算除 // — 当结果为正数时,取整; 11//5 =2; 11//4 = 2 当结果为负数时,向下取整;-11//5=-3; -11//4=-3 当分子分母都是float,结果为float型 ** — 计算幂; 11
本文向大家介绍浅谈JS的基础类型与引用类型,包括了浅谈JS的基础类型与引用类型的使用技巧和注意事项,需要的朋友参考一下 两种类型: ECMAScript变量包含两种不同类型的值:基本类型值、引用类型值; 基本类型值:指的是保存在栈内存中的简单数据段; 引用类型值:指的是那些保存在堆内存中的对象,意思是,变量中保存的实际上只是一个指针,这个指针指向内存中的另一个位置,由该位置保存对象; 两种访问方式
本文向大家介绍浅谈Django的缓存机制,包括了浅谈Django的缓存机制的使用技巧和注意事项,需要的朋友参考一下 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之
本文向大家介绍浅谈PHP的反射机制,包括了浅谈PHP的反射机制的使用技巧和注意事项,需要的朋友参考一下 1. 介绍 -- PHP5添加了一项新的功能:Reflection。这个功能使得phper可以reverse-engineer class, interface,function,method and extension。通过PHP代码,就可以得到某object的所有信息,并且可以和它交互。 -
本文向大家介绍浅谈Arrays.asList() 和ArrayList类型区别,包括了浅谈Arrays.asList() 和ArrayList类型区别的使用技巧和注意事项,需要的朋友参考一下 <pre name="code" class="html"><pre name="code" class="html">Arrays.asList() 将一个数组转化为一个List对象,这个方法会返回一个Ar