You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
const todo = {
id: 1,
text: "Buy milk",
due: new Date(2016, 11, 31)
};
const id = prop(todo, "id"); // any
const text = prop(todo, "text"); // any
const due = prop(todo, "due"); // any
阿里云最近在做活动,低至2折,真心觉得很划算了,可以点击本条内容或者链接进行参与:
https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=pxuujn3r
腾讯云最近在做活动,百款云产品低至 1 折,可以点击本条内容或者链接进行参与
为了保证的可读性,本文采用意译而非直译。
TypeScript 2.1 增加了对 对象扩展运算和 rest 属性提案的支持,该提案在 ES2018 中标准化。可以以类型安全的方式使用
rest
和spread
属性。对象 rest 属性
假设已经定义了一个具有三个属性的简单字面量对象
使用 ES6 解构语法,可以创建几个局部变量来保存相应属性的值。TypeScript 将正确地推断每个变量的类型:
这些都是正确的,但这到现在也啥新鲜的。除了提取感兴趣的一组属性之外,还可以使用
...
语法将所有剩余的属性收集到rest
元素中:TypeScript 会为得到结果的局部变量确定正确的类型。虽然
twitterHandle
变量是一个普通的字符串,但rest
变量是一个对象,其中包含剩余两个未被解构的属性。对象扩展属性
假设咱们希望使用
fetch()
API 发出 HTTP 请求。它接受两个参数:一个URL
和一个options
对象,options
包含请求的任何自定义设置。在应用程序中,可以封装对
fetch()
的调用,并提供默认选项和覆盖给定请求的特定设置。这些配置项类似如下:使用对象扩展,可以将两个对象合并成一个新对象,然后传递给
fetch()
方法对象扩展属性创建一个新对象,复制
defaultOptions
中的所有属性值,然后按照从左到右的顺序复制requestOptions
中的所有属性值,最后得到的结果如下:请注意,分配顺序很重要。如果一个属性同时出现在两个对象中,则后分配的会替换前面的。
当然,TypeScript 理解这种顺序。因此,如果多个扩展对象使用相同的键定义一个属性,那么结果对象中该属性的类型将是最后一次赋值的属性类型,因为它覆盖了先前赋值的属性:
制作对象的浅拷贝
对象扩展可用于创建对象的浅拷贝。假设咱希望通过创建一个新对象并复制所有属性来从现有
todo
项创建一个新todo
项,使用对象就可以轻松做到:实际上,你会得到一个新对象,所有的属性值都被复制:
现在可以修改
text
属性,但不会修改原始的todo
项:但是,新的todo项引用与第一个相同的
tags
数组。由于是浅拷贝,改变数组将影响这两个todo
如果想创建一个序列化对象的深拷贝,可以考虑使用
JSON.parse(JSON.stringify(obj))
或其他方法,如object.assign()
。对象扩展仅拷贝属性值,如果一个值是对另一个对象的引用,则可能导致意外的行为。keyof 和查找类型
JS 是一种高度动态的语言。在静态类型系统中捕获某些操作的语义有时会很棘手。以一个简单的
prop
函数为例:它接受一个对象和一个键,并返回相应属性的值。一个对象的不同属性可以有完全不同的类型,咱们甚至不知道
obj
是什么样子的。那么如何在 TypeScript 中编写这个函数呢?先尝试一下:
有了这两个类型注释,
obj
必须是对象,key
必须是字符串。咱们现在已经限制了两个参数的可能值集。然而,TS 仍然推断返回类型为any
:如果没有更进一步的信息,TypeScript 就不知道将为
key
参数传递哪个值,所以它不能推断出prop
函数的更具体的返回类型。咱们需要提供更多的类型信息来实现这一点。keyof 操作符号
在 JS 中属性名称作为参数的 API 是相当普遍的,但是到目前为止还没有表达在那些 API 中出现的类型关系。
TypeScript 2.1 新增加
keyof
操作符。输入索引类型查询或keyof
,索引类型查询keyof T
产生的类型是T
的属性名称。假设咱们已经定义了以下Todo
接口:各位可以将
keyof
操作符应用于Todo
类型,以获得其所有属性键的类型,该类型是字符串字面量类型的联合当然,各位也可以手动写出联合类型
"id" | "text" | "due"
,而不是使用keyof
,但是这样做很麻烦,容易出错,而且维护起来很麻烦。而且,它应该是特定于Todo
类型的解决方案,而不是通用的解决方案。索引类型查询
有了
keyof
,咱们现在可以改进prop
函数的类型注解。我们不再希望接受任意字符串作为key
参数。相反,咱们要求参数key
实际存在于传入的对象的类型上TypeScript 现在以推断
prop
函数的返回类型为T[K]
,这个就是所谓的索引类型查询
或查找类
型。它表示类型T
的属性K
的类型。如果现在通过prop
方法访问下面todo
的三个属性,那么每个属性都有正确的类型:现在,如果传递一个
todo
对象上不存在的键会发生什么编译器会报错,这很好,它阻止咱们试图读取一个不存在的属性。
另一个真实的示例,请查看与TypeScript编译器一起发布的
lib.es2017.object.d.ts
类型声明文件中Object.entries()方法:entries
方法返回一个元组数组,每个元组包含一个属性键和相应的值。不可否认,在返回类型中有大量的方括号,但是我们一直在寻找类型安全性。编辑中可能存在的bug没法实时知道,事后为了解决这些bug,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
原文:
https://mariusschulz.com/blog/object-rest-and-spread-in-typescript
https://mariusschulz.com/blog/keyof-and-lookup-types-in-typescript
交流
干货系列文章汇总如下,觉得不错点个Star,欢迎 加群 互相学习。
因为篇幅的限制,今天的分享只到这里。如果大家想了解更多的内容的话,可以去扫一扫每篇文章最下面的二维码,然后关注咱们的微信公众号,了解更多的资讯和有价值的内容。
The text was updated successfully, but these errors were encountered: