前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >TypeScript中的类型断言

TypeScript中的类型断言

作者头像
疯狂的技术宅
发布于 2020-06-19 03:52:06
发布于 2020-06-19 03:52:06
3.8K00
代码可运行
举报
文章被收录于专栏:京程一灯京程一灯
运行总次数:0
代码可运行

翻译:疯狂的技术宅

作者:Dr. Axel Rauschmayer

正文共:1820 字

预计阅读时间:10 分钟

本文是关于 TypeScript 中的 type assertions 的,它与其他语言中的类型强制转换有相似之处,并通过 as 运算符执行。


类型断言

类型断言使我们可以覆盖 TypeScript 为存储位置计算的静态类型,这对于解决类型系统的限制很有用。

类型断言与其他语言中的类型强制转换有相似之处,但是它们不会引发异常,并且在运行时也不做任何事情(它们确实会静态执行一些少量的检查)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1const data: object = ['a', 'b', 'c']; // (A)
2
3// @ts-ignore: Property 'length' does not exist on type 'object'.
4data.length; // (B)
5
6assert.equal(
7  (data as Array<string>).length, 3); // (C)
  • 在 A 行中,我们把 Array 的类型扩展为 object
  • 在 B 行中,我们看到此类型不允许访问任何属性。
  • 在 C 行中,我们用类型断言(运算符 as)告诉 TypeScript data 是一个Array。现在就可以访问属性 .length 了。

类型断言是不得已的方法,应尽可能的避免。他们(暂时)删除了静态类型系统为我们提供的安全网。

注意,在 A 行中,我们还覆盖了 TypeScript 的静态类型,不过是通过类型注释完成的。这种覆盖方式比类型声明要安全得多,因为你可以做的事情少得多。TypeScript 的类型必须能够分配给注释的类型。

类型断言的替代语法

TypeScript 对于类型断言有另一种“尖括号”语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1<Array<string>>data

该语法已经过时,并且与 React JSX 代码(在 .tsx 文件中)不兼容。

示例:声明一个接口

为了访问任意对象 obj 的属性 .name,我们暂时将 obj 的静态类型更改为 Named(A行和B行)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1interface Named {
2  name: string;
3}
4function getName(obj: object): string {
5  if (typeof (obj as Named).name === 'string') { // (A)
6    return (obj as Named).name; // (B)
7  }
8  return '(Unnamed)';
9}

示例:声明索引签名

在以下代码中,我们在行 A 用了类型断言 as Dict ,以便可以访问其推断类型为 object 的值的属性。也就是说,用静态类型 Dict 覆盖了推断的静态类型 object

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1type Dict = {[k:string]: any};
 2
 3function getPropertyValue(dict: unknown, key: string): any {
 4  if (typeof dict === 'object' && dict !== null && key in dict) {
 5    // %inferred-type: object
 6    dict;
 7
 8    // @ ts-ignore:元素隐式具有“any”类型,因为
 9    // 类型'string'的表达式不能用于索引类型'{}'。
10    // 在类型“ {}”上没有找到参数类型为'string'的索引签名。
11    dict[key];
12
13    return (dict as Dict)[key]; // (A)
14  } else {
15    throw new Error();
16  }
17}

与类型断言相关的构造

非空断言运算符(后缀 `!`)

如果值的类型是包含 undefinednull 类型的联合,则 non-nullish声明运算符(或 non-null 声明运算符)将从联合中删除这些类型。我们告诉 TypeScript:“这个值不能是 undefinednull。”因此,我们可以执行这两个值的类型所阻止的操作,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1const theName = 'Jane' as (null | string);
2
3// @ts-ignore: Object is possibly 'null'.
4theName.length;
5
6assert.equal(
7  theName!.length, 4); // OK
示例 – Maps: `.has()` 之后的 `.get()`

使用 Map 方法 .has() 之后,我们知道 Map 具有给定的键。遗憾的是,.get() 的结果不能反映这一点,这就是为什么我们必须使用 nullish 断言运算符的原因:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1function getLength(strMap: Map<string, string>, key: string): number {
2  if (strMap.has(key)) {
3    // We are sure x is not undefined:
4    const value = strMap.get(key)!; // (A)
5    return value.length;
6  }
7  return -1;
8}

由于 strMap 的值永远不会是 undefined,因此我们可以通过检查 .get() 的结果是否为 undefined 来检测丢失的 Map 条目(A 行):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1function getLength(strMap: Map<string, string>, key: string): number {
 2  // %inferred-type: string | undefined
 3  const value = strMap.get(key);
 4  if (value === undefined) { // (A)
 5    return -1;
 6  }
 7
 8  // %inferred-type: string
 9  value;
10
11  return value.length;
12}

定值断言

如果打开 strict 属性初始化,有时需要告诉 TypeScript 我们确实初始化某些属性——即使它认为我们不需要这样做。

这是一个例子,尽管 TypeScript 不应这样做,但它仍会报错:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1class Point1 {
 2  // @ts-ignore: Property 'x' has no initializer and is not definitely
 3  // assigned in the constructor.
 4  x: number;
 5
 6  // @ts-ignore: Property 'y' has no initializer and is not definitely
 7  // assigned in the constructor.
 8  y: number;
 9
10  constructor() {
11    this.initProperties();
12  }
13  initProperties() {
14    this.x = 0;
15    this.y = 0;
16  }
17}

如果我们在 A 行和 B 行中使用“定值分配断言”(感叹号),则错误会消失:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1class Point2 {
 2  x!: number; // (A)
 3  y!: number; // (B)
 4  constructor() {
 5    this.initProperties();
 6  }
 7  initProperties() {
 8    this.x = 0;
 9    this.y = 0;
10  }
11}

原文链接

https://2ality.com/2020/06/type-assertions-typescript.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端先锋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
TypeScript 中的顶级类型:any 和 unknown
在 TypeScript中,any 和 unknown 是包含所有值的类型。在本文中,我们将会研究它们是怎样工作的。
疯狂的技术宅
2020/06/11
2.5K0
TypeScript 中的顶级类型:any 和 unknown
一文学懂 TypeScript 的类型 [每日前端夜话0x39]
如果你认为这段代码非常神秘 —— 那么我同意你的意见。但是(我希望证明)这些符号还是相对容易学习的。一旦你能理解它们,就能马上全面、精确的理解这种代码,从而无需再去阅读冗长的英文说明。
疯狂的技术宅
2019/03/27
2K0
一文学懂 TypeScript 的类型 [每日前端夜话0x39]
一文读懂 TS 中 Object, object, {} 类型之间的区别
TypeScript 2.2 引入了被称为 object 类型的新类型,它用于表示非原始类型。在 JavaScript 中以下类型被视为原始类型:string、boolean、number、bigint、symbol、null 和 undefined。
阿宝哥
2020/04/08
18.1K0
一份不可多得的TypeScript系统入门整理
函数声明(Function Declaration)和函数表达式(Function Expression)
@超人
2021/07/29
1.8K0
一份不可多得的TypeScript系统入门整理
从TypeScript到ArkTS迁移的保姆级指导
本文通过提供简洁的约束指导如何将标准的TypeScript代码重构为ArkTS代码。尽管ArkTS是基于TypeScript设计的,但出于性能考虑,一些TypeScript的特性被限制了。因此,在ArkTS中,所有的TypeScript特性被分成三类。
小帅聊鸿蒙
2024/07/07
7750
从TypeScript到ArkTS迁移的保姆级指导
TypeScript 非空断言
使用这种方案,问题是解决了。但有没有更简单的方式呢?答案是有的,就是使用 TypeScript 2.0 提供的非空断言操作符:
阿宝哥
2020/04/08
20.7K0
TypeScript 简介及编码规范
TypeScript 是一种由微软开发的自由和开源的编程语言。它是 JavaScript 的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。
阿宝哥
2019/11/05
10.6K0
了不起的 TypeScript 入门教程
想学习 TypeScript 的小伙伴看过来,本文将带你一步步学习 TypeScript 入门相关的十四个知识点,详细的内容大纲请看下图:
阿宝哥
2020/06/10
7K0
Typescript常看常新
在看了同事推荐的ts教程后,发现自己还是有很多不会的,所以整理出一些自己学到的新知识点,希望各位也能有所收获!(我就写给自己看看,不要太当回事哈哈哈
y191024
2024/01/22
2500
Typescript常看常新
TS 从 0 到 1 - TypeScript 中的各种符号
! 后缀表达式可以用于断言操作对象是非 null 和非 undefined 类型。即 x!,将从 x 值域中排除 null 和 undefined。
Cellinlab
2023/05/17
1.6K0
30道TypeScript 面试问题解析
TypeScript 是 Microsoft 开发的JavaScript 的开源超集,用于在不破坏现有程序的情况下添加附加功能。
前端达人
2021/07/16
4.4K0
细数 TS 中那些奇怪的符号
TypeScript 是一种由微软开发的自由和开源的编程语言。它是 JavaScript 的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。
阿宝哥
2020/09/10
6K1
细数 TS 中那些奇怪的符号
TypeScript类型断言-类型的声明和转换
为什么要有断言这个概念?TS中并不能判断在使用联合类型时具体是那种类型?当我们不知道是什么类型的情况下要使用某个类型特有的属性或者方法,那么就可以用断言来实现,它实际上是对编辑器做了提前告知的行为,但是并不能保证运行中报错。主要有两种方式来实现,具体如下:
不叫猫先生
2023/11/20
4000
TypeScript类型断言-类型的声明和转换
以淘宝店铺为例,谈谈 TypeScript ESLint 规则集考量
ESLint 在项目中已经是大家见惯不惯的存在,你可能很厌烦动不动跳出来的 ESLint 报错,也可能很享受经过统一校验的工工整整的代码,无论如何,我的意见是,在稍微正式点的项目中都要有 ESLint 的存在,无论是直接使用简单的 recommend 配置如 extends: ['eslint: recommend'],还是精心研究了一整套适用于自己的规则集,Lint 工具的最大帮助就是保持语法统一,至少项目中的所有 JavaScript 文件应使用统一的单双引号、分号、缩进等风格(仅靠编辑器并不能保证)。
用户3806669
2022/03/03
2.7K0
Typescript 高级用法以及项目实战问题
unknown 指的是「不可预先定义的类型」,在很多场景下,它可以替代 any 的功能同时保留静态检查的能力。
山月
2021/08/10
2K0
TypeScript的另一面:类型编程
作为前端开发的趋势之一,TypeScript 正在越来越普及,很多人像我一样写了 TS 后再也回不去了,比如写再小的demo也要用 TS(得益于ts-node[1]),JS 只有在配置文件如Webpack(实际上,接下来肯定会有用TS写配置文件的趋势,如Vite)、ESLint等时才会用到。但同样,也有部分开发者对TS持有拒绝的态度,如nodemon的作者就曾表示自己从来没有使用过TS(见 #1565[2])。但同样还有另外一部分人认为TS学习成本太高,所以一直没有开始学习的决心。
zz_jesse
2021/07/30
1.7K0
TypeScript基础(一)基本类型与类型运算
TypeScript是一种开源的编程语言,它是JavaScript的超集,意味着所有的JavaScript代码都可以在TypeScript中运行。TypeScript添加了静态类型检查和其他一些新特性,以提高代码的可读性、可维护性和可扩展性。
can4hou6joeng4
2023/11/17
2500
深入浅出TypeScript | 青训营笔记
TS(TypeScript)是一种由Microsoft开发和维护的编程语言,它是JavaScript的超集,支持静态类型检查、类、接口、泛型等特性。TS最终会被编译为标准的JavaScript代码,因此可以运行在任何支持JavaScript的环境中。
心安事随
2024/07/29
980
深入浅出TypeScript | 青训营笔记
Typescript真香秘笈
本文由 IMWeb 首发于 IMWeb 社区网站 imweb.io。点击阅读原文查看 IMWeb 社区更多精彩文章。 1. 前言 2018年Stack Overflow Developer的调研(https://insights.stackoverflow.com/survey/2018/)显示,TypeScript已经成为比JavaScript更受开发者喜爱的编程语言了。 之前我其实对于typescript没有太多好感,主要是认为其学习成本比较高,写起代码来还要多写很多类型声明,并且会受到静态类型检查
用户1097444
2022/06/29
5.7K0
Typescript真香秘笈
【Vuejs】301- Vue 3.0前的 TypeScript 最佳入门实践
然鹅最近的一个项目中,是 TypeScript+ Vue,毛计喇,学之...…真香!
pingan8787
2019/07/30
4.4K0
【Vuejs】301- Vue 3.0前的 TypeScript 最佳入门实践
相关推荐
TypeScript 中的顶级类型:any 和 unknown
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文