這 六個(gè) TS 新特性經(jīng)常用到,用了之后我再也離不開它!
今天來介紹一下 TypeScript 的一些較新的功能和進(jìn)展,這些是我在日常工作中經(jīng)常在用的功能。
在構(gòu)造函數(shù)中直接定義屬性
Typescript 中可以通過構(gòu)造函數(shù)的參數(shù)直接定義屬性,我們來先看早期的做法:
- class Note {
- public title: string;
- public content: string;
- private history: string[];
- constructor(title: string, content: string, history: string[]) {
- this.title = title;
- this.content = content;
- this.history = history;
- }
- }
采用 ts 中簡寫的語法:
- class Note {
- constructor(
- public title: string,
- public content: string,
- private history: string[]
- ){
- // 這里不用在寫 this.title = title
- }
- }
它可能看上去不像是有屬性的類,但它確實(shí)有,利用的是 Typescript 提供的簡寫形式 — 用構(gòu)造函數(shù)的參數(shù)直接定義屬性。
這個(gè)簡寫語法做了很多:
- 聲明了一個(gè)構(gòu)造函數(shù)參數(shù)及其類型
- 聲明了一個(gè)同名的公共屬性
- 當(dāng)我們 new 出該類的一個(gè)實(shí)例時(shí),把該屬性初始化為相應(yīng)的參數(shù)值
空值合并
??其實(shí)沒啥意思,就是Nullish Coalescing (空值合并)。聽起來有點(diǎn)懵,我們直接上代碼
- const i = undefined
- const k = i ?? 5
- console.log(k) // 5
- // 3.9.2編譯
- const i = undefined;
- const k = i !== null && i !== void 0 ? i : 5;
- console.log(k); // 5
這個(gè)時(shí)候你肯定是想說了這樣不就完了嗎?
- let k = i || 5
雖然這樣也用,但是你不覺得很不嚴(yán)謹(jǐn)嗎?如果i = 0呢?
私有類字段
TypeScript 3.8 將支持 ECMAScript 私有字段,千萬別和 TypeScript private 修飾符 混淆。
這是在 TypeScript 中具有私有類字段的類:
- class Animal {
- #name: string;
- constructor(theName: string) {
- this.#name = theName;
- }
- }
在private關(guān)鍵字之上使用私有類字段的區(qū)別在于前者有更好的運(yùn)行時(shí)保證。用private關(guān)鍵字聲明的 TypeScript 字段將在編譯后的JavaScript代碼中成為常規(guī)字段。另一方面,私有類字段在編譯后的代碼中仍然是私有的。
試圖在運(yùn)行時(shí)訪問私有類字段將導(dǎo)致語法錯(cuò)誤。我們也使用瀏覽器開發(fā)工具也檢查不了私有類字段。
有了私有類字段,我們終于在JavaScript中得到了真正的隱私。
命名元組類型(Labeled tuple types)
命名元組類型適需要 TypeScript 4.0及以上版本才能使用,它極大的改善了我們的開發(fā)體驗(yàn)及效率,先來看一個(gè)例子:
- type Address = [string, number]
- function setAddress(...args: Address) {
- // some code here
- console.log(args)
- }
當(dāng)我們這樣定義函數(shù)入?yún)⒑?,在使用函?shù)時(shí),編輯器的智能提示只會(huì)提示我們參數(shù)類型,丟失了對參數(shù)含義的描述。

為了改善這一點(diǎn),我們可以通過 Labeled tuple types,我們可以這樣定義參數(shù):
- type Address = [streetName: string, streetNumber: number]
- function setAddress(...args: Address) {
- // some code here
- console.log(args)
- }

這樣,在調(diào)用函數(shù)時(shí),我們的參數(shù)就獲得了相應(yīng)的語義,這使得代碼更加容易維護(hù)。
模板字面量類型
自 ES6 開始,我們就可以通過模板字面量(Template Literals)的特性,用反引號來書寫字符串,而不只是單引號或雙引號:
- const message = `text`;
正如 Flavio Copes 所言,模板字面量提供了之前用引號寫的字符串所不具備的特性:
- 定義多行字符串非常方便
- 可以輕松地進(jìn)行變量和表達(dá)式的插值
- 可以用模板標(biāo)簽創(chuàng)建 DSL(Domain Specific Language,領(lǐng)域特定語言)
模板字面量類型和 JavaScript 中的模板字符串語法完全一致,只不過是用在類型定義里面:
- type topBottom = "top" | "bottom"
- type leftRight = "left" | "right"
- type Position = `${topBottom }-${leftRight }`

當(dāng)我們定義了一個(gè)具體的字面量類型時(shí),TypeScript 會(huì)通過拼接內(nèi)容的方式產(chǎn)生新的字符串字面量類型。
實(shí)用類型
TypeScript為你提供了一組實(shí)用類型,讓你在現(xiàn)有類型的基礎(chǔ)上構(gòu)建新的類型。有許多實(shí)用類型涵蓋了不同的情況,例如選擇類型屬性來復(fù)制,大寫字母,或使所有的屬性都是可選的。
下面是一個(gè)使用 Omit工具的例子,它復(fù)制了原始類型的所有屬性,除了我們選擇不包括的那些。

- type User = {
- name: string
- age: number
- location: string
- }
- type MyUser = Omit<User, 'name'>
上面這些就是我工作經(jīng)常使用的一部分,另外一些后面在分享,就這?