TypeScript 常用的新玩法

大家好,我是若川。持续组织了6个月源码共读活动,感兴趣的可以点此加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列


上周分享了 ts 入门以及常用的小技巧《TS 在项目中的 N 个实用小技巧 - 文字稿》,然后发现有好几个关注了公众号来提问的(结果我开了小冰的自动回复,有了以下奇怪的对话

b7d81cdd4ec50709d58ea16d467011c6.png

当看到想要回复的时候,发现...(怪我没有开通知,略微尴尬 ~~ 😷

02ec16b7df1adbda85eed430352a12a3.png

那就只能发文来讲一讲了(希望对应的小伙伴能看到)。回顾下之前的题目,问怎么能让他的返回结果是 string

const user = {name: 'amy', age: 18}
function getPersonInfo(key: keyof typeof user) {return user[key];
}const userName = getPersonInfo('name'); // string | number

解决方法肯定是泛型。这里需要关注的一个点是,泛型是可以只定义传参不传的,例如下文的 T extends keyof UserType 就限定了 T 一定是 user 中的一个 key,这个时候将参数的类型定义定义成 T ,那么返回类型自然是 UserType[T] 了,这里返回类型不定义也成,ts 能根据下面的写法自动推断出来。这种通过泛型结合 extends 的写法,可以一定情况下来辅助指定参数的类型。

const user = {name: 'amy', age: 18}
type UserType =  typeof userfunction getPersonInfo<T extends keyof UserType>(key: T): UserType[T] {return user[key];
}const userName = getPersonInfo('name'); // string

专门开了篇文章,那肯定得写点什么。上一篇文章做 ts 的分享的时候,发现市面上大多文章都是基于 ts3.x 的版本去做分析讲解的,就算高级进阶篇,很多也只是讲到一些常用的工具函数就戛然而至。甚至 google 搜索到的位于搜索引擎的 ts 中文网(据接触,有不少有中文文档就看中文文档的小伙伴),也只是更新到 3.1,从 npm 的发布记录来看也是四年前的版本了。所以,来写点大家说得相对少的,但是我们日常也可以感知到新玩意吧~~

正文开始

c91ce8b54a64fe14011dbb09f3748f5d.png


几个对 ECMAScript 提案的跟进

一、可选操作链和空值合并

es2020 中,新增了一个深受大家喜爱的属性:proposal-optional-chaining ,通常来说我们要使用需要结合 babel 配合转译来兼容低版本的浏览器(使用 @babel/preset-env  的 ES2020 版本,或者使用 @babel/plugin-proposal-optional-chaining 插件。

另外还有一个运算符 ?? 空值合并(nullish coalescing operator)。例如 a ?? b 可以等同于 (a !== null && a !== undefined) ? a : b; 这个在做一些数据接口校验的时候有些作用。

typescript 3.7 版本中,针对上述说的两种操作符都及时做了支持,也就意味着如果你只使用了 typescript ,而没使用 babel  的场景也可以用它来玩(场景不多见,知道有这么回事就好)

let x = foo?.bar.baz();
// => let x = foo === null || foo === void 0 ? void 0 : foo.bar.baz();let x = foo ?? bar();
// let x = foo !== null && foo !== void 0 ? foo : bar();

二、私有字段(Private Fields)

typescirpt 3.8 中支持使用 # 表示私有字段,另外在 4.3 版本中也支持了方法和 getter 都能有类似的写法。demo 如下:

class Person {#name: stringconstructor(name: string) {this.#name = name;}#someMethod() {//...}get #someValue() {return 100;}
}let person = new Person('Amy');
person.#name
// Property '#name' is not accessible outside class 'Person'

其实跟 private 关键词差不多,不同的点在于上述代码,如果使用的是 private 属性,你通过 person['name'] 这种手段还是可以访问到,而你使用 person['#name'] 依然会报错

三、短路运算符

三个运算符新增 *= 的操作:&&= 、 ||=  和  ??=

跟常见的 let a += a+1 的感觉差不多,只不过这里的操作运算符是 && ||?? 而已,一个实际 demo,下面三种写法都是一个意思。

const a = { duration: 50, title: '' };a.duration ||= 10; // demo1, => 50a.duration = a.duration || 10; // demo2, => 50if (!a.duration) { // demo3, => 50a.duration = 10; 
}


语言特性的优化

一、Type-Only Imports and Export

翻译过来,就是仅仅导入导出 type 。有一些用 ts 的小伙伴可能经常会看到一些warning 提示,找不到 xx 定义。但是点进文件一看,那些定义都好端端的写在文件中,于是一头雾水甚至直接忽略 warning 提示了。

942e40716b828d99bd98a9b26ebf1b6d.png

这其实是该功能会解决的一个问题,举一个例子来说明这情况产生的原因:

// types.ts
export type User = {... };
export type UserList = User[];// index.ts
export { User, UserList } from './types'; // ts types
export { getUser, CreateUser } from './user'; // js function

从逻辑上看上面的代码并没有任何问题,但是在底层,这是一个被称之为「导入省略」的功能起的作用。通常 babel 在编译的时候,是一个个处理文件的,针对 ts 他一般是先删除类型,然后再进行编译。我们如果光看 index.ts ,实际都并不知道 User  和  CreateUser 谁是一个 ts type 的定义而谁是 js 运行时需要的东西。于是 babel 只能被迫的将所有东西都保留,于是转译后的文件为

// types.js
-- empty file --// index.js
export { User, UserList } from './types'; // ts types
export { getUser, CreateUser } from './user'; // js function

而在 typescript 3.8 之后,我们的解决方法可以变成下述写法。针对 type 的导入或者导出,babel会在删除类型的环节,直接将 import type ... 或者 export type xxx 这类的语句直接去掉。

// index.ts
export type { User, UserList } from './types'; // ts types
export { getUser, CreateUser } from './user'; // js function// => babel 转换后
export { getUser, CreateUser } from './user'; // only js function

另外,在 4.5 的版本中,支持了对于某个变量局部使用 type 的写法,就不用说类型和 js 的函数要拆成两条语句了

// ts 3.8
import type { BaseType } from "./some-module.js";
import { someFunc } from "./some-module.js";// => ts 4.5
import { someFunc, type BaseType } from "./some-module.js";


二、模版字符串

跟 es6 的模版字符串类似,不过是用于类型。此外,用在模板字符串类型中的泛型或类型别名,类型必须满足是string | number | bigint | boolean | null | undefined之一(也就是基础类型)。

应该有不少小伙伴都听说过,知乎上 ts 体操也是慢慢的从这特性出来开始越来越火。实际应用个人觉得会更多对于一些需要字符串拼接的场景,减少枚举。这里简单的列举一下例子

2.1 字符串组合场景

以下是一个 antd 中的 tootoolTip 组件,他有 12 个方向,传统写法,我们可能会直接枚举 12 种,写起来有那么一丢丢累,而且还很容易手抖不小心拼错。

5f542e99c18973d0ff511b7b06471468.png

结合字符串模版和首字母大写的 Capitalize 方法,我们可以将纯枚举罗列,变成以下的组合:

2c73a90f705322c7e80fb35029009441.png

2.2 跟 infer 结合解析路由参数

网上看到的,话不多说,直接上代码。将 :id 转成 {id: string},不是特别理解的可以复习复习 infer 然后多看几眼自己尝试写一写。

a891bf61848c14fd5378c7e9b2c8950c.png

既然路由参数可以解析,那么 url 参数解析其实同理,想要将 a=1&b=2 转换成 { a:'1', b:'2' } 的话,自己撸的一个小思路:

4dfb001a43afb47d62782a9b39399fb1.png

另外还有一个在 map 中使用 as rename 的方法,结合模版语法,我们可以在写一些通用函数的时候偷偷懒

type Getters<T> = {[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]
};interface Person {name: string;age: number;
}type PersonGetters = Getters<Person>
/* => {getName: () => string;getAge: () => number;
} */

再有,通过字符串变量, lodashget 方法也可以更加精准的定义,还有 vuex 的模版等等。在 TSconf2020 中 anders 也给了很多不错的例子在 github 上,有兴趣的可以自行查阅:https://github.com/ahejlsberg/tsconf2020-demos/blob/master/template/main.ts。总之,就很多很多可以玩的玩法可以探索的,只要愿意。

d7929cec356564e6cad226b7c67bb8af.png

三、解构变量可以显式标记为未使用

使用解构的用法时,如果我们只需要第二个参数,而不需要第一个参数时,以前 ts 的语法检查总是会报错。在 typescript 4.2 版本之后,可以使用 _ 可以告诉 ts 这解构变量标记是未使用的,比如以下例子,只会报 second 没有被使用。

function getValues() {return ['a', 'b'];
}
const [_first, second] = getValues();
// 已声明“second”,但从未读取其值。

一个注意事项,如果你使用了 typescript-eslint 那可能编辑器的 eslint 检查还是会提示错误,需要配置让 no-unused-vars 规则允许下划线的变量不被使用。

rules: {"@typescript-eslint/no-unused-vars": ["error", { "ignoreRestSiblings": true }]
},


四、新增 Await 关键字

在 4.5 版本中支持,相当于可以快速获取 promise 的返回值了,结合 typeof 使用,或许可以节省几句对类型的 import

const a = Promise.resolve('100')
// A = string
type A = Awaited<typeof a>;
// B = number
type B = Awaited<Promise<Promise<number>>>;
// C = boolean | number
type C = Awaited<boolean | Promise<number>>;


最后

除了上述的一些描述,ts 每次更新当然也会有很多例如编译速度提升啊,更加符合 js 逻辑的一些自动推导的优化等等,这里就不做过多概述。还有一些配置项的新增,有兴趣的小伙伴可以自行查阅官方文档~~

相关回顾

1、TS 在项目中的 N 个实用小技巧 - 文字稿

生活总结

1、分享-前端小白的成长历程文字稿

2、2021 总结 | 鳗鱼 - 平凡的生活

3、2020 总结 | 鳗鱼 - 一起来吃鳗鱼饭吧

4、2019 总结 | 鳗鱼 - 写在 24 岁门口的自己

b7610e6cd3c85ca711b0811b47c96ef1.gif

················· 若川简介 ·················

你好,我是若川,毕业于江西高校。现在是一名前端开发“工程师”。写有《学习源码整体架构系列》20余篇,在知乎、掘金收获超百万阅读。
从2014年起,每年都会写一篇年度总结,已经坚持写了8年,点击查看年度总结。
同时,最近组织了源码共读活动,帮助3000+前端人学会看源码。公众号愿景:帮助5年内前端人走向前列。

85341992d730937fa8a327d499c286d1.png

扫码加我微信 ruochuan02、拉你进源码共读

今日话题

略。分享、收藏、点赞、在看我的文章就是对我最大的支持~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/274815.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试官是怎样高效面试的(面试官的“套路”

大家好&#xff0c;我是若川。持续组织了6个月源码共读活动&#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列最近正…

微服务负载均衡实现高可用_使用负载平衡实现大容量可用性

微服务负载均衡实现高可用Written by Yona Gidalevitz由Yona Gidalevitz撰写 Most users of the web are blissfully unaware of the sheer scale of the process responsible for bringing content across the Internet. There are literally miles of Internet between you …

19岁中专学历是怎么在广州找到前端工作的?

大家好&#xff0c;我是若川。持续组织了8个月源码共读活动&#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列本文来…

tcp 接收端优雅的写法_如何更优雅地接收设计反馈

tcp 接收端优雅的写法重点 (Top highlight)It’s rare to meet a designer that doesn’t take pride in their work. After all, we are creatives and it’s what we love to do. Although design is teachable, there is a bit of natural skill and talent that comes into…

一份 2.5k star 的《React 开发思想纲领》

大家好&#xff0c;我是若川。持续组织了6个月源码共读活动&#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列翻译自…

文案写作软件_11种可改善网站用户体验的文案写作技术

文案写作软件Written by John Stevens约翰史蒂文斯 ( John Stevens)撰写 When we talk about user experience and your website, it is easy to get caught up in the site’s design and navigation options. While that is important, the words you place on the page are…

张小龙谈用户体验

原文&#xff1a;http://sd.csdn.net/a/20120510/2805483.html从Foxmail到腾讯“七星级产品”QQ邮箱&#xff0c;再到腾讯核武器级产品微信。在外界看来&#xff0c;腾讯副总裁、广州研发部总经理张小龙作风低调&#xff0c;很少接受正式的媒体采访。然而作为当今国内最优秀的产…

web开发集成数字证书_每个数字设计师都应该知道的Web开发的七个原则

web开发集成数字证书A career path into digital design is often winding, meaning many practitioners come from adjacent fields as diverse as graphic design, web development, research, or even anthropology. As a result, two people working in a similar role may…

前端工程师生产环境 debugger 技巧

大家好&#xff0c;我是若川。持续组织了6个月源码共读活动&#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列导言开…

figma设计_Figma与Adobe XD:我们如何选择下一个设计工具

figma设计The time came for changes and our design team started raising the topic again about how we should consider moving away from Sketch. This is not the first time this question came to mind, but this time seems like it was serious. Last summer we cons…

一个小厂前端 Leader 如何筛选候选人?

大家好&#xff0c;我是若川。持续组织了8个月源码共读活动&#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列本文作…

figma设计_如何在Figma中构建设计入门套件(第1部分)

figma设计Figma教程 (Figma Tutorial) Do you like staring at a blank canvas every time you start a new project in Figma?每次在Figma中启动新项目时&#xff0c;您是否喜欢盯着一块空白的画布&#xff1f; I’m guessing you’re not a big fan right, but it’s a pra…

纯靠技术,很难进入大厂了。。。

日前&#xff0c;国务院印发《“十四五”时期就业促进规划的通知》&#xff0c;其中明确指出&#xff0c;要完善终身学习体系&#xff0c;推进高水平大学开放教育资源&#xff0c;畅通在职人员继续教育与终身学习通道。为响应国家政策&#xff0c;现临时扩大招生规模&#xff0…

十天学会ASP.Net——(8)

1. ajax入门AJAX Extensions工具箱 &#xff08;1&#xff09;实现又刷新改变字体大小和无刷新改变字体大小 页面设计&#xff1a; 前台页面设计&#xff1a; 首先需要在用到ajaxExtensions控件的位置之前放置一个ScriptManager控件&#xff0c;它将在浏览页面时不可见&#xf…

聊聊 computed 影响性能的场景

大家好&#xff0c;我是若川。持续组织了8个月源码共读活动&#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列前言在…

saej1929_(1929年-2020年)

saej1929Milton Glaser, the legendary graphic designer who co-founded New York Magazine, created the iconic ‘I ❤ NY’ logo, the psychedelic Bob Dylan poster, and the Brooklyn Brewery logo, passed away yesterday at the age of 91 on his birthday, June 26, 2…

Chap2-构造函数语意学

如果一个类没有任何constructor&#xff0c;那么会有一个default constructor被隐式的声明出来&#xff0c;一个implicit default constructor将是一个trivial&#xff08;无用的&#xff09;constructor。但是在某些情况下&#xff0c;implicit default constructor将是一个no…

【热点】React18正式版发布,未来发展趋势是?

大家好&#xff0c;我是若川。持续组织了8个月源码共读活动&#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列2022年…

不要重新发明轮子_是否重新发明轮子

不要重新发明轮子Design is a profession that thrives on creativity. Us designers are constantly trying to innovate by thinking outside the box. We’ve seen design evolve across all sectors — print, digital, product, architecture etc. We have gone from type…

点击页面元素,这个Vite插件竟然帮我打开了Vue组件文件!超级好用!

大家好&#xff0c;我是若川。持续组织了8个月源码共读活动&#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列前言这…