自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Typescript 一些令人又愛又恨的內(nèi)容 — Type Guard、Narrowing

開發(fā) 前端
今天介紹了 TypeScript 中用來檢查類型的方法,假如讀者日后遇到類似這種問題不妨可以多加利用 Type Guard 進行檢查。

本文已經(jīng)過授權(quán)發(fā)布。

由于 JavaScript 本身是弱語言,因此在開發(fā)上常因為不知道變量的類型是什么而感到苦惱,即使借由命名的方式讓變量的定位稍微明確一點,我們還是很難一眼就知道他的類型甚至當此變量是一個 object 時我們更難知道里面有哪些 key,因此大家漸漸開始使用 TypeScript 作為主要的開發(fā)工具。

不曉得大家在利用 TypeScript 進行開發(fā)時,有沒有覺得 TypeScript 在檢查類型這塊特別惱人,雖然知道這些類型檢查的舉動是非常好的,可以幫助我們減少許多可能會發(fā)生的潛在錯誤,今天就要來談?wù)劗斘覀冊陂_發(fā)上遇到這種問題時該如何解決。

場景一

不曉得大家有沒有遇過這種問題,今天想要讓這個變量查看是否符合 enum 中的某一個值,結(jié)果 TypeScript 就噴錯給你看了,像下面這樣。

其實要解決上面的紅字方法非常多,首先是開大絕使用 @ts-ignore 讓錯誤消失,當然這個方法非常不好,等于是叫 TypeScript 不要檢查下面這行了。

這時候可能會想到另一個方法,上面的錯誤信息是說 male 沒有被 assign 到 GENDER 這個 type,所以我只要強制塞給他這個 type 就好,就像這樣:

可是這樣寫仍然不好,等于你強制轉(zhuǎn)變這個變量了,讓這個變量失去了彈性,接下來我們介紹比較好用的方法,就讓我們繼續(xù)看下去吧!

Type Guard

首先要介紹的是 Type Guard,Type Guard 顧名思義就是類型的看守者,剛剛 TypeScript 會報錯就是因為 type 不一樣,所以只要我們建立一個類型的看守者,讓 TypeScript 知道這個變量一定會符合我 enum 中的某一個 value 時,這時候就不會出現(xiàn)紅字了,而通常 Type Guard 會寫成一個 function 像這樣:

const assertsIsGender = (gender: any) : gender is GENDER => {
return Object.values(GENDER).includes(gender)
}

這時候我們可以發(fā)現(xiàn) gender 這個變量已經(jīng)從 string type 變成 GENDER type 了,所以即便我很無聊的再做一次 includes 的判斷 TypeScript 也不會報任何錯誤了。

這邊我在指定 gender 這個值之前先指派這個變量是一個 string type,這個動作很重要,如果沒有先指派變量類型再給值的話這個變數(shù)就沒辦法順利改變 type 了。

場景二

不曉得大家有沒有遇過在 API 回傳的資料,也會因為資料對應(yīng)到的 enum 的值不同而發(fā)生錯誤,像下面這樣:

有了上面 Type Guard 的觀念后,這時候的讀者一定知道要寫一個 function 來處理這段錯誤信息:

的確錯誤信息沒有了,但很奇怪的是 gender 竟然變成 never type 了,而這個就是 Type Guard 會做到的一個類型保護機制叫:Narrowing。

類型收窄(Narrowing)

Narrowing 翻成白話文就是類型收窄,在 TypeScript 的世界中每一個 enum 基本上都是獨立存在彼此之間是沒有交集的,關(guān)系圖就像下面這樣:

所以要進行兩個 enum 間的類型轉(zhuǎn)換就很容易產(chǎn)生出一個可能不會存在的型別,對于可能不會存在的類別 TypeScript 把這個型別定義為 never,而這時候當我們使用了 Type Guard 的技巧,TypeScript 就會自動把類型收窄成 never type,而不是自動轉(zhuǎn)換成另一個 enum 了。

當然聰明的你可能會這樣想:那我只要把 function return 定義成另一個 enum 不就好了,這樣就可以確保我 Type Guard 的結(jié)果一定會類型轉(zhuǎn)換成我想要的 enum,像下面這樣:

這樣寫看起來的確沒有什麼問題,我們想要的結(jié)果也從類型收窄變成了類型轉(zhuǎn)換,但這樣做其實就有點不太符合 Type Guard 的精神,畢竟 Type Guard 要做的是類型檢查而不是類型轉(zhuǎn)換,而且假如我們要做的是類型轉(zhuǎn)換,這樣寫也會讓這個 function 的復用性不高,因此我們接下來要介紹比較好的類型轉(zhuǎn)型方法。

Mapper enum

首先我們可以先想想如何讓類型轉(zhuǎn)換這件事被復用,我們不妨把想法簡單化,就是建立一個 function 把 A 型態(tài)轉(zhuǎn)換成 B 型態(tài),而這時候就必須要利用 TypeScript 中的 Generics 泛型這個技巧了,像下面這樣:

const createEnumMapper = <T>(mapping: T) => (value: keyof T | null) : T[keyof T] | undefined => {
return value === null ? undefined : mapping[value]
}

這個 createEnumMapper 的 function 是一個 currying function,第一個變數(shù)傳入的是 enum 本身,這時候 TypeScript 的 Generics 就會知道我的 T 就是跟 enum 本身有關(guān)。

為了讓這個 Generics 可以正確的把兩個 enum mapping起來,我們必須要先建立一個 object 把兩個 enum 的key value配對像下面這樣:

const mapper = {
[BE_GENDER.MALE]: FE_GENDER.MALE,
[BE_GENDER.FEMALE]: FE_GENDER.FEMALE
}

由于我們上面的 mapper 是把 enum 的 value 當成 key,所以我們只要帶入 data 的值就可以直接轉(zhuǎn)換了,像下面這樣:

這時候就可以發(fā)現(xiàn)我們成功的把 BE_GENDER type 的值轉(zhuǎn)成 FE_GENDER type 的值了,而且也不需要動用到 Type Guard 的觀念。

總結(jié)

今天介紹了 TypeScript 中用來檢查類型的方法,假如讀者日后遇到類似這種問題不妨可以多加利用 Type Guard 進行檢查,而不是直接開大絕用 @ts-ignore 或者 as 這兩種方法,除了介紹類型檢查外也介紹了如何進行類型轉(zhuǎn)換,希望這些方法都可以讓讀者未來在使用上都不會有太多的問題。

責任編輯:姜華 來源: 大遷世界
相關(guān)推薦

2013-12-06 10:11:48

Windows 8Windows 7Windows 8.1

2022-03-04 12:09:25

SQL數(shù)據(jù)量多表查詢

2014-12-04 09:58:59

PHP

2019-08-06 08:47:18

運營商流量套餐4G服務(wù)

2019-11-19 15:08:47

Tomcat服務(wù)器底層

2011-10-18 09:35:28

虛擬化瘦客戶端Windows Thi

2019-11-25 11:24:09

技術(shù)周刊

2020-02-27 21:37:33

物聯(lián)網(wǎng)IOT物聯(lián)網(wǎng)應(yīng)用

2023-07-18 19:11:21

配置信令系統(tǒng)

2014-03-19 15:41:21

編程語言編程規(guī)則

2014-08-25 09:59:54

注解Android

2020-11-09 16:00:26

LinuxLinux內(nèi)核

2021-04-09 09:20:10

Windows 10微軟瀏覽器

2017-12-01 10:05:59

C++編程開發(fā)

2023-02-13 14:37:46

ChatGPT人工智能

2014-06-20 14:47:08

2020-03-10 20:06:38

釘釘微博熱搜

2021-11-12 11:31:27

數(shù)據(jù)結(jié)構(gòu)算法貪心解法

2014-07-23 10:19:02

小米4

2021-09-09 18:12:22

內(nèi)存分段式網(wǎng)絡(luò)
點贊
收藏

51CTO技術(shù)棧公眾號