日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
幾個一看就會的TypeScript小技巧

這篇文章就來分享一些很多人不知道的小技巧吧,都是學(xué)完就能用起來的那種。

創(chuàng)新互聯(lián)公司是一家企業(yè)級云計(jì)算解決方案提供商,超15年IDC數(shù)據(jù)中心運(yùn)營經(jīng)驗(yàn)。主營GPU顯卡服務(wù)器,站群服務(wù)器,服務(wù)器托管,海外高防服務(wù)器,機(jī)柜大帶寬、租用·托管,動態(tài)撥號VPS,海外云手機(jī),海外云服務(wù)器,海外服務(wù)器租用托管等。

keyof any

TypeScript 有一個內(nèi)置類型叫做 Record,它的作用是根據(jù)傳入的索引和值的類型構(gòu)造新的索引類型。

它的實(shí)現(xiàn)就是通過映射類型的語法構(gòu)造一個索引類型:

type Record = { [P in K]: T };

那么問題來了,這個 K 怎么約束呢?

有同學(xué)說 K 不是索引么?那應(yīng)該是 string,也就是 K extends string。

但是 JS 的屬性可以是 string、number、symbol 這三種類型的。

那我知道了,要 K extends string | number | symbol。

不不不,TypeScript 有個編譯選項(xiàng)叫做 keyofStringsOnly,開啟了那么就就只會用 string 作為索引,否則才是 string | number | symbol:

這還與編譯選項(xiàng)有關(guān),那這里改怎么約束呢?

看下 TS 源碼里是怎么定義 Record 的:

type Record = { [P in K]: T; };

它用了 keyof any,難道這個 keyof any 就能動態(tài)得到 key 支持的類型么?

我們試一下,不開啟 keyofStringsOnly 時:

開啟 keyofStringsOnly 時:

妙啊,這樣就能動態(tài)獲取當(dāng)前支持的 key 的類型了。

需要約束某個類型參數(shù)為索引 Key 時,用 keyof any 動態(tài)獲取比寫死 string | number | symbol 更好。

object 和 Record

object 和 RecordTypeScript 里有三個類型比較難區(qū)分,就是 object、Object、{} 這幾個。

其實(shí)只要記住 object 不能接受原始類型 就可以了,其余兩個差不多,只不過 {} 是個空對象,沒有索引。

所以 number 就可以賦值給 {}、Object 類型,但是不能賦值給 object 類型:

其實(shí),你看源碼會發(fā)現(xiàn)大家不會用 object 來約束,而是用 Record 來約束索引類型,這倆其實(shí)是一樣的,但是 Record 更語義化一些。

Record 創(chuàng)建了一個 key 為任意 string,value 為任意類型的索引類型:

所以,平時約束索引類型的時候就可以用 Record 代替 object。

而且你會在很多源碼里看到這種寫法,比如下面是 Nest.js 源碼里的:

-readonly

映射類型可以構(gòu)造一個新的索引類型,并且構(gòu)造的過程中做一些修改。

比如構(gòu)造一個新的索引類型,把所有的 Key 變?yōu)榭蛇x:

type ToPartial = { [Key in keyof T]?: T[Key] }

或者構(gòu)造一個新的索引類型,加上 readonly 的修飾:

type ToReadonly = { readonly [Key in keyof T]: T[Key]; }

但很多人不知道也可以去掉已有的修飾的,用 - 號,減去的意思:

比如去掉 ? 是 -? :

type ToRequired = { [Key in keyof T]-?: T[Key] }

那去掉 readonly 自然就是 -readonly:

type ToMutable = { -readonly [Key in keyof T]: T[Key] }

我最近看到 Promise.all 的類型定義就用到這個了:

類型參數(shù) T 是 待處理的 promise 數(shù)組,返回值是 Promise 的 value 對應(yīng)的數(shù)組,用 Awaited 取出 value 的類型。

Awaited 是 TS 內(nèi)置的一個高級類型,用于取出 Promise 返回值類型的:

返回的是數(shù)組類型,那為啥還可以用映射類型的語法呢?

因?yàn)閿?shù)組類型也是索引類型呀,索引類型的意思就是聚合多個元素的類型,數(shù)組、對象、class 都是索引類型。

當(dāng)然,主要還是為了講 -readonly 的語法,可以去掉 readonly 的修飾。

this

方法里可以調(diào)用 this,比如這樣:

class Dong {
name: string;

constructor() {
this.name = "dong";
}

hello() {
return 'hello, I\'m ' + this.name;
}
}

const dong = new Dong();
dong.hello();

用對象.方法名的方式調(diào)用的時候,this 就指向那個對象。

但是方法也可以用 call 或者 apply 調(diào)用:

call 調(diào)用的時候,this 就變了,但這里卻沒有被檢查出來 this 指向的錯誤。

如何讓編譯器能夠檢查出 this 指向的錯誤呢?

其實(shí)方法是可以指定 this 的類型的:

class Dong {
name: string;

constructor() {
this.name = "dong";
}

hello(this: Dong) {
return 'hello, I\'m ' + this.name;
}
}

這樣,當(dāng) call/apply 調(diào)用的時候,就能檢查出 this 指向的對象是否是對的:

而且,TypeScript 也提供了一個內(nèi)置的高級類型 ThisParameterType 用于提取 this 的類型:

它的實(shí)現(xiàn)很簡單,就是通過模式匹配提取 this 的類型到 infer 聲明的局部變量里返回:

? 和 ??

最后是一個比較常用的語法,TS 支持 ? 的可選鏈語法,也可以通過 ?? 指定默認(rèn)值:

const dong = data?.name ?? 'dong';

編譯之后會變成這樣:

做了空值檢查,也設(shè)置了默認(rèn)值 dong。

很簡單和有用的一個語法,但很多人寫 ts 還是沒把它用起來。

總結(jié)

TypeScript 有很多靈活的語法,小技巧很多。

今天分享了一些大家可能不知道的技巧:

  • keyof any 可以動態(tài)獲取 key 支持的類型,根據(jù) keyofStringsOnly 的編譯選項(xiàng),可以用來約束索引。
  • object 不能接收原始類型,而 {} 和 Object 都可以,這是它們的區(qū)別。
  • object 一般會用 Record 代替,約束索引類型更加語義化。
  • 映射類型語法可以創(chuàng)建索引類型,并且加上 readonly 或 ? 的修飾,其實(shí)也可以用 -readonly、-? 去掉。
  • ? 和 ?? 分別代表空判斷和默認(rèn)值,是寫 TS 很常用的一個語法。
  • this 的類型是可以約束的,而且也可以用內(nèi)置的高級類型 ThisParameterTypes 來取。

這幾個小技巧都是看一遍就會的那種,下次寫 TS 類型的時候就可以用起來了。


當(dāng)前標(biāo)題:幾個一看就會的TypeScript小技巧
當(dāng)前URL:http://www.dlmjj.cn/article/cocihpo.html