偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

這幾個(gè) TypeScript 類(lèi)型,90% 的人說(shuō)不出原因

開(kāi)發(fā) 前端
條件類(lèi)型當(dāng) checkType(左邊的類(lèi)型)是類(lèi)型參數(shù)的時(shí)候,會(huì)有 distributive 的性質(zhì),也就是傳入聯(lián)合類(lèi)型時(shí)會(huì)把每個(gè)類(lèi)型單獨(dú)傳入做計(jì)算,最后把結(jié)果合并返回。

有這樣幾個(gè) TypeScript 類(lèi)型,大家先試著猜下 res 都是啥:

第一個(gè):

傳入的類(lèi)型參數(shù)為聯(lián)合類(lèi)型 1 | 'a',問(wèn) res 是啥

type Test<T> = T extends number ? 1 : 2;

type res = Test<1 | 'a'>;

第二個(gè):

傳入的類(lèi)型參數(shù)為 boolean,問(wèn) res 是啥

type Test<T> = T extends true ? 1 : 2;

type res = Test<boolean>;

第三個(gè):

傳入的類(lèi)型參數(shù)為 any,問(wèn) res 是啥

type Test<T> = T extends true ? 1 : 2;

type res = Test<boolean>;

第四個(gè):

傳入的類(lèi)型參數(shù)為 never,問(wèn) res 是啥

type Test<T> = T extends true ? 1 : 2;

type res = Test<never>;

先記一下自己的答案,接下來(lái)我公布正確答案,大家看下猜對(duì)了幾個(gè)。

答案公布

第一個(gè)類(lèi)型 res 是 1 | 2

再來(lái)看第二個(gè)類(lèi)型,res 也是 1 | 2

接下來(lái)是第三個(gè)類(lèi)型,res 也是 1 | 2

最后是第四個(gè)類(lèi)型,res 是 never

不管答對(duì)了幾個(gè)都沒(méi)關(guān)系,關(guān)鍵是要知道它的原因,接下來(lái)我解釋下:

原因解釋

第一個(gè)類(lèi)型 res 是 1 | 2

有同學(xué)可能會(huì)說(shuō),這里傳入的是聯(lián)合類(lèi)型呀,也不是 number,為啥結(jié)果是這樣呢?

因?yàn)楫?dāng)條件類(lèi)型的左邊是類(lèi)型參數(shù)時(shí),會(huì)有 distributive 的性質(zhì),也就是把聯(lián)合類(lèi)型的每個(gè)類(lèi)型單獨(dú)傳入求值,把每個(gè)的結(jié)果合并成聯(lián)合類(lèi)型,這叫做分布式條件類(lèi)型。

這里的 T extends number 的左邊是類(lèi)型參數(shù) T,傳入的是聯(lián)合類(lèi)型 1 | 'a',所以會(huì)把 1 傳入求值、把 2 傳入求值,最后把結(jié)果合并成聯(lián)合類(lèi)型,也就是 1 | 2。

再來(lái)看第二個(gè)類(lèi)型,res 也是 1 | 2

為啥這里也是 1 | 2 呢, 剛才說(shuō)的分布式條件類(lèi)型是針對(duì)聯(lián)合類(lèi)型的呀?

沒(méi)錯(cuò),boolean 其實(shí)也是聯(lián)合類(lèi)型,所以會(huì)把 true 和 false 分別傳入求值,最后結(jié)果合并成聯(lián)合類(lèi)型,所以是 1 | 2。

接下來(lái)是第三個(gè)類(lèi)型,res 也是 1 | 2

同學(xué)可能會(huì)說(shuō):哦,我知道了,any 也是聯(lián)合類(lèi)型。

錯(cuò),any 不是聯(lián)合類(lèi)型,這里是因?yàn)闂l件類(lèi)型對(duì) any 做了特殊處理,如果左邊是 any,那么直接把 trueType 和 falseType 合并成聯(lián)合類(lèi)型返回。

最后是第四個(gè)類(lèi)型,res 是 never

咋還出來(lái)個(gè) never,不是只有 1 和 2 么?

這里確實(shí)也是 TS 的特殊處理,當(dāng)條件類(lèi)型左邊是 never 時(shí),直接返回 never。

你說(shuō)了這么多,我怎么知道是不是真的呢,萬(wàn)一是你編的呢?

有懷疑很正常,這也是應(yīng)該有的態(tài)度,不過(guò)這些確實(shí)都是真的,接下來(lái)我從源碼來(lái)驗(yàn)證下。

從 TS 源碼解釋原因

這里的重點(diǎn)不在如何讀 TypeScript 源碼上,我就略過(guò)過(guò)程了,直接給結(jié)果。

對(duì)如何閱讀 TypeScript 源碼感興趣的同學(xué),可以看我之前的一篇文章:《我讀 TypeScript 源碼的秘訣都在這里了》,或者看我剛上線的掘金小冊(cè)《TypeScript 類(lèi)型體操通關(guān)秘籍》,小冊(cè)里會(huì)帶大家從源碼解釋各種類(lèi)型的原理。

先來(lái)解釋第一個(gè)聯(lián)合類(lèi)型 + 條件類(lèi)型的情況:

type Test<T> = T extends number ? 1 : 2;

type res = Test<1 | 'a'>;

TypeScript 在處理到條件類(lèi)型 Conditional Type 的時(shí)候,會(huì)設(shè)置一個(gè) isDistributive 的屬性,根據(jù)類(lèi)型參數(shù)是不是 checkType(左邊的類(lèi)型)來(lái)設(shè)置。

因?yàn)?T extends number 的 checkType 是 T,所以這里的 isDistributive 就是 true,也就是它是分布式條件類(lèi)型。

那么是分布式條件類(lèi)型會(huì)做什么處理呢?

會(huì)在求值的時(shí)候把每個(gè)類(lèi)型單獨(dú)傳入求值,最后把結(jié)果合并。

對(duì)應(yīng)的源碼是這樣的:

這里都不用解釋了,注釋都寫(xiě)的很清楚了, T extends U ? X : Y 當(dāng)傳入的 T 是 A | B 時(shí),結(jié)果是 (A extends U ? X : Y)|(B extends U ? X : Y)。

這就是分布式條件類(lèi)型遇到聯(lián)合類(lèi)型時(shí)的處理。

所以,源碼走到了 mapTypeWithAlias 這個(gè)分支,就是做每個(gè)類(lèi)型單獨(dú)傳入求值的。

我們從源碼驗(yàn)證了分布式條件類(lèi)型的特性!

接下來(lái)再來(lái)看第二個(gè)類(lèi)型,當(dāng)條件類(lèi)型 + boolean 時(shí):

type Test<T> = T extends true ? 1 : 2;

type res = Test<boolean>;

前面說(shuō) boolean 也是聯(lián)合類(lèi)型,這是不是真的呢?

debug 發(fā)現(xiàn)它也走到這個(gè)分支了。說(shuō)明條件成立,boolean 是 union 或者 never

驗(yàn)證一下:

這里的 flags 就是每一個(gè)位表示一種類(lèi)型,然后通過(guò)位運(yùn)算的按位與來(lái)判斷是否是那種類(lèi)型:

這種方式占用空間小,計(jì)算速度快,很多框架都是這樣來(lái)標(biāo)識(shí)類(lèi)型的,比如 React。

所以,從結(jié)果來(lái)看 boolean 是聯(lián)合類(lèi)型,也就是 true | false。那自然也會(huì)觸發(fā)分布式條件類(lèi)型的特性,把 true 和 false 單獨(dú)傳入求值,最后把結(jié)果合并。

然后是第三個(gè)類(lèi)型,當(dāng)條件類(lèi)型 + any 時(shí):

type Test<T> = T extends true ? 1 : 2;

type res = Test<any>;

debug 會(huì)發(fā)現(xiàn)并沒(méi)有走到 mapType 那個(gè)分支,而走了另一個(gè)分支:

這就說(shuō)明條件不滿(mǎn)足,any 不是聯(lián)合類(lèi)型呀,我們也可以通過(guò) flags 看下:

按位與的結(jié)果是 0,也說(shuō)明了它不是 union 和 never。

那為啥結(jié)果還是 1 | 2 呢?

繼續(xù)往下走,看條件類(lèi)型的求值邏輯,會(huì)發(fā)現(xiàn)這樣一段代碼:

注釋是 Return union of trueType and falseType for 'any' since it matches anything,意思是是返回 trueType 和 falseType 的聯(lián)合類(lèi)型,因?yàn)?any 匹配任何類(lèi)型。

原因不就出來(lái)了么。(不得不說(shuō),TS 源碼的注釋寫(xiě)的真不錯(cuò))

然后就是最后一個(gè)類(lèi)型,當(dāng)條件類(lèi)型 + never 時(shí):

type Test<T> = T extends true ? 1 : 2;

type res = Test<never>;

為啥直接返回了 never 呢?

debug 會(huì)發(fā)現(xiàn) never 也走到 mapType 這個(gè)分支了:

啥情況,never 又不是聯(lián)合類(lèi)型,咋分呀。

人家條件里確實(shí)寫(xiě)的是 Union 或者 Never:

說(shuō)明肯定對(duì) Never 做了特殊處理,別著急,我們繼續(xù)往下看。

繼續(xù)往下走會(huì)發(fā)現(xiàn) Union 和 Never 在這里分叉了:

然后 mapType 里對(duì) never 類(lèi)型直接就給返回了該類(lèi)型,也就是 never:

這就是為啥結(jié)果既不是 trueType、也不是 falseType,而是 never。

至此,我們通過(guò)源碼來(lái)驗(yàn)證了上面說(shuō)的原因的真實(shí)性。

總結(jié)

TypeScript 的類(lèi)型系統(tǒng)有一些特殊的設(shè)計(jì):

條件類(lèi)型當(dāng) checkType(左邊的類(lèi)型)是類(lèi)型參數(shù)的時(shí)候,會(huì)有 distributive 的性質(zhì),也就是傳入聯(lián)合類(lèi)型時(shí)會(huì)把每個(gè)類(lèi)型單獨(dú)傳入做計(jì)算,最后把結(jié)果合并返回。這叫做分布式條件類(lèi)型。

此外,條件類(lèi)型遇到 never 會(huì)直接返回 never,遇到 any 會(huì)返回 trueType 和 falseType 的聯(lián)合類(lèi)型。

再就是 boolean 也是聯(lián)合類(lèi)型,是 true | false。

類(lèi)似這種特殊的地方還是不少的,這些我都總結(jié)在了 《TypeScript 類(lèi)型體操通關(guān)秘籍》的小冊(cè)里,會(huì)全面系統(tǒng)的講 TypeScript 類(lèi)型編程,還有會(huì)教大家如何 TypeScript 源碼來(lái)解釋這些類(lèi)型的原理。感興趣的可以看一下,保證不坑。而且現(xiàn)在買(mǎi)很便宜的,只有 17 塊。

責(zé)任編輯:姜華 來(lái)源: 神光的編程秘籍
相關(guān)推薦

2025-03-24 10:11:06

SpringJava開(kāi)發(fā)

2019-10-30 09:02:04

JavaCPU 線程

2020-08-31 10:21:41

5G波束天線

2021-06-11 13:59:22

CSS原子類(lèi)

2020-02-03 09:29:32

JavaScript代碼斷點(diǎn)

2021-10-27 10:07:59

GitHub代碼開(kāi)發(fā)者

2019-02-28 20:20:43

Python技巧編程語(yǔ)言

2020-04-20 14:50:02

前端技巧優(yōu)化

2023-11-30 08:19:52

偽類(lèi)CSS

2020-09-18 06:48:21

Python編程語(yǔ)言

2022-05-20 15:27:41

React工具Vue

2024-07-01 08:31:14

Spring工具類(lèi)代碼

2020-08-24 13:15:59

Python代碼描述符

2020-08-24 15:25:27

Python 開(kāi)發(fā)運(yùn)維

2018-11-21 08:12:19

人工智能失業(yè)機(jī)器

2025-05-23 08:00:00

VLAN虛擬局域網(wǎng)網(wǎng)絡(luò)

2020-07-24 08:51:54

Java編程語(yǔ)言開(kāi)發(fā)

2022-02-21 16:16:24

災(zāi)難恢復(fù)解決方案備份

2022-04-12 08:43:21

Python內(nèi)置模塊

2018-04-18 06:56:26

iPhone手機(jī)電量
點(diǎn)贊
收藏

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