15.【TypeScript 教程】类型保护

简介: 15.【TypeScript 教程】类型保护

TypeScript 类型保护

本节介绍的类型保护 TypeScript 类型检查机制的第二个部分,我们可以通过 typeofinstanceofin字面量类型 将代码分割成范围更小的代码块,在这一小块中,变量的类型是确定的。


1. 解释

类型保护是指缩小类型的范围,在一定的块级作用域内由编译器推导其类型,提示并规避不合法的操作。


2. typeof

通过 typeof 运算符判断变量类型,下面看一个之前介绍函数重载时的例子:

function reverse(target: string | number) {
  if (typeof target === 'string') {
    target.toFixed(2) // Error,在这个代码块中,target 是 string 类型,没有 toFixed 方法
    return target.split('').reverse().join('')
  }
  if (typeof target === 'number') {
    target.toFixed(2) // OK
    return +[...target.toString()].reverse().join('')
  }
 
  target.forEach(element => {}) // Error,在这个代码块中,target 是 string 或 number 类型,没有 forEach 方法
}

代码解释:


第 2 行,通过 typeof 关键字,将这个代码块中变量 target 的类型限定为 string 类型。


第 6 行,通过 typeof 关键字,将这个代码块中变量 target 的类型限定为 number 类型。


第 11 行,因没有限定,在这个代码块中,变量 target 是 string 或 number 类型,没有 forEach 方法,所以报错。


3. instanceof

instanceof 与 typeof 类似,区别在于 typeof 判断基础类型,instanceof 判断是否为某个对象的实例:

class User {
  public nickname: string | undefined
  public group: number | undefined
}
 
class Log {
  public count: number = 10
  public keyword: string | undefined
}
 
function typeGuard(arg: User | Log) {
  if (arg instanceof User) {
    arg.count = 15 // Error, User 类型无此属性
  }
 
  if (arg instanceof Log) {
    arg.count = 15 // OK
  }
}

代码解释:

第 12 行,通过 instanceof 关键字,将这个代码块中变量 arg 的类型限定为 User 类型。

第 16 行,通过 instanceof 关键字,将这个代码块中变量 arg 的类型限定为 Log 类型。

4. in

in 操作符用于确定属性是否存在于某个对象上,这也是一种缩小范围的类型保护。

class User {
  public nickname: string | undefined
  public groups!: number[]
}
 
class Log {
  public count: number = 10
  public keyword: string | undefined
}
 
function typeGuard(arg: User | Log) {
  if ('nickname' in arg) {
    // (parameter) arg: User,编辑器将推断在当前块作用域 arg 为 User 类型
    arg.nickname = 'mybj'
  }
 
  if ('count' in arg) {
    // (parameter) arg: Log,编辑器将推断在当前块作用域 arg 为 Log 类型
    arg.count = 15
  }
}

代码解释:

第 12 行,通过 in 关键字,将这个代码块中变量 arg 的类型限定为 User 类型。

第 17 行,通过 in 关键字,将这个代码块中变量 arg 的类型限定为 Log 类型。

5. 字面量类型保护

用字面量类型那一节的例子改造一下来介绍字面量类型保护:

type Success = {
  success: true,
  code: number,
  object: object
}
 
type Fail = {
  success: false,
  code: number,
  errMsg: string,
  request: string
}
 
function test(arg: Success | Fail) {
  if (arg.success === true) {
    console.log(arg.object) // OK
    console.log(arg.errMsg) // Error, Property 'errMsg' does not exist on type 'Success'
  } else {
    console.log(arg.errMsg) // OK
    console.log(arg.object) // Error, Property 'object' does not exist on type 'Fail'
  }
}

代码解释:

第 15 行,通过布尔字面量,将这个代码块中变量 arg 的类型限定为 Success 类型。

第 18 行,通过布尔字面量,将这个代码块中变量 arg 的类型限定为 Fail 类型。

6. 小结

类型保护就是让编译器帮助我们缩小类型范围,在编译阶段规避掉一些不必要的错误,提高代码质量。

相关文章
|
22天前
|
JavaScript 前端开发 Java
TypeScript 类型兼容性
TypeScript 类型兼容性
|
22天前
|
JavaScript 前端开发
typescript 混合类型
typescript 混合类型
|
6天前
|
JavaScript 前端开发 IDE
TypeScript中的声明文件(.d.ts):扩展类型系统
TypeScript的`.d.ts`声明文件为JS库提供类型信息,增强IDE支持,如自动完成和类型检查。通过声明合并,可在全局作用域定义类型。示例包括为`my-library`创建声明模块,导出函数和接口。声明文件通常存于`@types`或指定`typeRoots`。用于旧JS代码的类型注解,如`myGlobalObject`。学习更多,参阅TypeScript官方文档。分享你的TS声明文件经验!
|
18天前
|
JavaScript 前端开发 安全
TypeScript:静态类型的动态语言
【6月更文挑战第9天】TypeScript是JavaScript的静态类型超集,解决JS类型安全问题,提供更强的代码组织和维护。它引入静态类型、接口和类,增强类型安全,减少运行时错误。TS与JS无缝集成,兼容现有库和框架,拥有丰富的开发工具和活跃社区。广泛应用在各种规模项目中,尤其提升复杂前端应用的代码质量。学习TypeScript对提升开发效率和代码可靠性极具价值。
26 10
|
16天前
|
前端开发 JavaScript 安全
TypeScript作为一种静态类型的JavaScript超集,其强大的类型系统和面向对象编程特性为微前端架构的实现提供了有力的支持
【6月更文挑战第11天】微前端架构借助TypeScript提升开发效率和代码可靠性。 TypeScript提供类型安全,防止微前端间通信出错;智能提示和自动补全加速跨代码库开发;重构支持简化代码更新。通过定义公共接口确保一致性,用TypeScript编写微前端以保证质量。集成到构建流程确保顺利构建打包。在微前端场景中,TypeScript是强有力的语言选择。
30 2
|
22天前
|
JavaScript
TypeScript 泛型类型
TypeScript 泛型类型
|
24天前
|
JavaScript 编译器
35.【TypeScript 教程】编译选项
35.【TypeScript 教程】编译选项
16 2
|
2天前
|
JavaScript 安全
TypeScript类型(数字、字符串、字面量、数组、元组、枚举、对象等)
TypeScript类型(数字、字符串、字面量、数组、元组、枚举、对象等)
5 0
|
2天前
|
JavaScript
TypeScript类型申明
TypeScript类型申明
6 0
|
22天前
|
JavaScript 算法
TypeScript 类型推论
TypeScript 类型推论