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.pswp.cn/news/274815.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/274815.shtml
英文地址,請注明出處:http://en.pswp.cn/news/274815.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《Programming in Lua 3》讀書筆記(十二)

日期&#xff1a;2014.7.14 PartⅡ Object-Oriented ProgrammingLua中實現面向對象編程。“如同OOP對象&#xff0c;table擁有狀態&#xff1b;如同OOP對象&#xff0c;table擁有標識符---self&#xff0c;用來與其他變量做區分&#xff0c;而且兩個table擁有同樣的值也是…

(轉)AS3中的stage,this,root的區別

要了解這個問題就要先對flash中的顯示對象結構有一個大概的了解&#xff1a; 第一級&#xff1a;舞臺&#xff1b; 第二級&#xff1a;當前SWF&#xff1b; 第三級&#xff1a;各種容器及可視對象&#xff08;如&#xff1a;文本框&#xff0c;位圖……&#xff09;&#xff1b…

面試官是怎樣高效面試的(面試官的“套路”

大家好&#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 …

Visual Studio 2008自帶的Windows 系統使用的各種圖標、光標和動畫文件

1&#xff0c;Visual Studio 2008自帶的1000多個 Windows 系統使用的各種圖標、光標和動畫文件 在Visual Studio 2008的安裝目錄下&#xff0c; /Microsoft Visual Studio 9.0/Common7/VS2008ImageLibrary/2052文件夾下面&#xff0c;有一個VS2008ImageLibrary.zip&#xff0c;…

Android中導入第三方jar

右鍵工程&#xff0c;Build path,Java build path,選擇libraries在右邊的按鈕中點擊“Add Library”選擇“User library”,點擊“下一步”點擊“User librarys”按鈕在出現的界面中點擊“New..”按鈕在彈出的界面中隨便起一個名字&#xff0c;點擊“確定”點擊“Add jars”按鈕…

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…

C++頭文件一覽表

傳統 C   #include <assert.h>    //設定插入點   #include <ctype.h>//字符處理   #include <errno.h>//定義錯誤碼   #include <float.h>//浮點數處理   #include <fstream.h>//文件輸入&#xff0f;輸出   #include &l…

一份 2.5k star 的《React 開發思想綱領》

大家好&#xff0c;我是若川。持續組織了6個月源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列翻譯自…

asp.net生成jason給js

[WebMethod(EnableSession true)][ScriptMethod]public static object TEST(string testval){int type 0;string message "";int precent 0;return new { type type, message message, precent precent };} 轉載于:https://www.cnblogs.com/bulege/archive/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…

Table.Rows.Remove(dr)和Table.Delete()的區別

一個DataRow對象剛被創建之后其狀態是Detached&#xff0c;是孤立的一個存在&#xff0c;所以建立了DataRow之后在DataRow中的單元填充了數據后還要通過DataTable.Rows.Add(DataRow)方法將此DataRow添加到DataTable&#xff0c;DataRow添加到DataTable后, 這個DataRow的狀態就…

張小龍談用戶體驗

原文&#xff1a;http://sd.csdn.net/a/20120510/2805483.html從Foxmail到騰訊“七星級產品”QQ郵箱&#xff0c;再到騰訊核武器級產品微信。在外界看來&#xff0c;騰訊副總裁、廣州研發部總經理張小龍作風低調&#xff0c;很少接受正式的媒體采訪。然而作為當今國內最優秀的產…

如何高效學習前端新知識,我推薦這些~

眾所周知&#xff0c;關注公眾號可以了解學習掌握技術方向&#xff0c;學習優質好文&#xff0c;落實到自己項目中。還可以結交圈內好友&#xff0c;讓自己融入到積極上進的技術氛圍&#xff0c;促進自己的技術提升。話不多說&#xff0c;推薦這些優質前端公眾號前端之神100w閱…

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…

【轉】CentOS 6.6 升級GCC G++ (當前最新版本為v6.1.0) (完整)

原文地址&#xff1a;https://www.cnblogs.com/lzpong/p/5755678.html 我這里是centos7 升級到gcc8.1&#xff0c;過程差不多&#xff0c;參考這篇文章&#xff0c;記錄一下。 ---原文--- CentOS 6.6 升級GCC G (當前最新GCC/G版本為v6.1.0) 沒有便捷方式, yum update.... yu…

Hadoop:mapreduce的splitsize和blocksize

參考&#xff1a; Hadoop MapReduce中如何處理跨行Block和UnputSplit https://stackoverflow.com/questions/17727468/hadoop-input-split-size-vs-block-size https://stackoverflow.com/questions/30549261/split-size-vs-block-size-in-hadoop轉載于:https://www.cnblogs.co…

前端工程師生產環境 debugger 技巧

大家好&#xff0c;我是若川。持續組織了6個月源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列導言開…

bmp轉jpg(使用libjpeg)

jpg壓縮原理可以參考這篇文章http://hi.baidu.com/tiandsp/item/f5a2dcde6ef1405bd73aae41&#xff0c;我很早以前轉的一篇文章。 沒有使用libjpeg的壓縮代碼可以看看這篇文章http://hi.baidu.com/tiandsp/item/9b5843c58a3b4474cfd4f841&#xff0c;也是我很早以前轉的。 這次…