成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

什么?函數(shù)類(lèi)型重載還可以動(dòng)態(tài)生成?

開(kāi)發(fā) 前端
ts 函數(shù)重載一共有三種寫(xiě)法:declare function、interface、交叉類(lèi)型 &。當(dāng)重載比較多的時(shí)候,直接列出來(lái)還是比較麻煩的,這時(shí)候可以用類(lèi)型編程來(lái)動(dòng)態(tài)生成函數(shù)重載。

重載是指一個(gè)函數(shù)可以有不同的參數(shù)和返回值,也就是有不同的函數(shù)簽名。

ts 支持函數(shù)重載,可以為同一個(gè)函數(shù)定義多個(gè)不同的類(lèi)型:

重載的寫(xiě)法一共有三種(估計(jì)大多數(shù)人只會(huì)一種):

declare function func(name: string): string;
declare function func(name: number): number;

這種大家比較常用,聲明兩個(gè)同名函數(shù),就能達(dá)到重載的目的:

函數(shù)可以用 interface 的方式聲明,同樣,也可以用 interface 的方式聲明函數(shù)重載:

函數(shù)類(lèi)型可以取交叉類(lèi)型,也就是多種類(lèi)型都可以,其實(shí)也是函數(shù)重載的意思:

重載雖然是很有用的特性,但有的時(shí)候重載多了寫(xiě)起來(lái)還是挺麻煩的。

比如 ts 提供的 lib.dom.ts 里就有這樣的類(lèi)型定義:

因?yàn)槊糠N參數(shù)對(duì)應(yīng)不同的返回值,所以它就重載了這么多。

這樣寫(xiě)起來(lái)也太麻煩了吧,能不能用類(lèi)型編程動(dòng)態(tài)生成呢?

考慮下重載的三種寫(xiě)法,declare 和 interface 不行,但是 & 可以呀,能不能我傳入一個(gè)聯(lián)合類(lèi)型,然后它給返回交叉類(lèi)型呢?

比如這樣:

都提示出來(lái)了肯定是可以的,我們看下砸實(shí)現(xiàn)的吧:

聯(lián)合轉(zhuǎn)交叉函數(shù)參數(shù)有逆變的性質(zhì),也就是類(lèi)型縮小,比如參數(shù)能同時(shí)傳 A、B、C 的話(huà),參數(shù)類(lèi)型怎么定義?

肯定是 A、B、C 的交集呀,也就你 A & B & C 的交叉類(lèi)型,這樣就可以接收 A、B、C 的參數(shù)了。

可以利用這個(gè)性質(zhì)實(shí)現(xiàn)聯(lián)合轉(zhuǎn)交叉。

比如這樣:

都提示出來(lái)了肯定是可以的,我們看下砸實(shí)現(xiàn)的吧:

聯(lián)合轉(zhuǎn)交叉

函數(shù)參數(shù)有逆變的性質(zhì),也就是類(lèi)型縮小,比如參數(shù)能同時(shí)傳 A、B、C 的話(huà),參數(shù)類(lèi)型怎么定義?

肯定是 A、B、C 的交集呀,也就你 A & B & C 的交叉類(lèi)型,這樣就可以接收 A、B、C 的參數(shù)了。

可以利用這個(gè)性質(zhì)實(shí)現(xiàn)聯(lián)合轉(zhuǎn)交叉。

type UnionToIntersection<U> = 
(U extends U ? (x: U) => unknown : never) extends (x: infer R) => unknown
? R
: never

測(cè)試一下:

這里的類(lèi)型參數(shù) U 是傳入的聯(lián)合類(lèi)型,加一個(gè) U extends U 是為了觸發(fā)分布式條件類(lèi)型的特性。

什么是分布式條件類(lèi)型呢?

當(dāng)類(lèi)型參數(shù)為聯(lián)合類(lèi)型,并且在條件類(lèi)型左邊直接引用該類(lèi)型參數(shù)的時(shí)候,TypeScript 會(huì)把每一個(gè)元素單獨(dú)傳入來(lái)做類(lèi)型運(yùn)算,最后再合并成聯(lián)合類(lèi)型,這種語(yǔ)法叫做分布式條件類(lèi)型。

比如這樣一個(gè)聯(lián)合類(lèi)型:

type Union = 'a' | 'b' | 'c';

我們想把其中的 a 大寫(xiě),就可以這樣寫(xiě):

type UppercaseA<Item extends string> = 
Item extends 'a' ? Uppercase<Item> : Item;

回到聯(lián)合轉(zhuǎn)交叉的這個(gè)高級(jí)類(lèi)型:

加一個(gè) U extends U 或者 U extends any 就能觸發(fā)分布式條件類(lèi)型的特性,讓聯(lián)合類(lèi)型分成每一個(gè)類(lèi)型單獨(dú)傳入做計(jì)算,最后把結(jié)果合并成聯(lián)合類(lèi)型。

然后再把它放到函數(shù)參數(shù)的位置,構(gòu)造一個(gè)函數(shù)類(lèi)型,通過(guò)模式匹配的方式提取參數(shù)的類(lèi)型到 infer 聲明的局部變量 R 里返回。

這樣的結(jié)果就是交叉類(lèi)型。

原因上面說(shuō)過(guò)了,函數(shù)參數(shù)有逆變的性質(zhì),傳入聯(lián)合類(lèi)型會(huì)返回交叉類(lèi)型。

實(shí)現(xiàn)了聯(lián)合轉(zhuǎn)交叉之后,函數(shù)重載也就可以寫(xiě)出來(lái)了:

比如三個(gè)重載的返回值分別是 Aaa、Bbb、Ccc:

我們想基于這個(gè)生成重載的類(lèi)型定義,傳入聯(lián)合類(lèi)型返回重載的函數(shù):

就可以這樣寫(xiě):

type UnionToOverloadFunction<T extends keyof ReturnValueMap> = 
UnionToIntersection<
T extends any ? (type: T) => ReturnValueMap[T] : never
>;

類(lèi)型參數(shù) T 是 ReturnValueMap 里的 key,約束為 keyof ReturnValueMap。

通過(guò) T extends any 觸發(fā)聯(lián)合類(lèi)型在分布式條件類(lèi)型中的分發(fā)特性,讓 'aaa' 'bbb' 'ccc' 分別傳入做計(jì)算,返回構(gòu)造出的函數(shù)類(lèi)型的聯(lián)合。

我們先單獨(dú)測(cè)試下這部分:

可以看到返回的是構(gòu)造出的函數(shù)類(lèi)型的聯(lián)合類(lèi)型。

然后就用上面的 UnionToIntersection 轉(zhuǎn)交叉就可以了:

這樣就實(shí)現(xiàn)了重載函數(shù)的動(dòng)態(tài)生成:

對(duì)比下最開(kāi)始那種寫(xiě)法:

是不是清爽多了!而且還可以寫(xiě)一些動(dòng)態(tài)邏輯。

總結(jié)

ts 函數(shù)重載一共有三種寫(xiě)法:declare function、interface、交叉類(lèi)型 &。

當(dāng)重載比較多的時(shí)候,直接列出來(lái)還是比較麻煩的,這時(shí)候可以用類(lèi)型編程來(lái)動(dòng)態(tài)生成函數(shù)重載。

我們實(shí)現(xiàn)了聯(lián)合轉(zhuǎn)交叉,利用了函數(shù)參數(shù)的逆變性質(zhì),也就是當(dāng)參數(shù)可能是多個(gè)類(lèi)型時(shí),會(huì)返回它們的交叉類(lèi)型。

然后又利用分布式條件類(lèi)型的性質(zhì),當(dāng)傳入聯(lián)合類(lèi)型時(shí),會(huì)把類(lèi)型單獨(dú)傳入做計(jì)算,最后把結(jié)果合并成聯(lián)合類(lèi)型。

利用這個(gè)實(shí)現(xiàn)了傳入聯(lián)合類(lèi)型返回構(gòu)造出的函數(shù)的聯(lián)合類(lèi)型,然后再結(jié)合聯(lián)合轉(zhuǎn)交叉就實(shí)現(xiàn)了函數(shù)重載的動(dòng)態(tài)生成。

當(dāng)你寫(xiě)重載寫(xiě)的太多的時(shí)候,不妨試一下用類(lèi)型編程的方式動(dòng)態(tài)生成吧!

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

2018-08-08 14:25:17

2023-04-14 15:44:20

TypeScrip函數(shù)重載

2021-03-03 08:05:53

C++項(xiàng)目函數(shù)

2020-07-21 18:54:21

Rust類(lèi)型轉(zhuǎn)換語(yǔ)言

2022-07-30 23:45:09

內(nèi)存泄漏檢測(cè)工具工具

2020-11-04 07:36:06

Redis二進(jìn)制數(shù)據(jù)庫(kù)

2022-10-09 10:02:09

Python3.12

2022-04-21 14:50:50

Python農(nóng)歷命令

2024-06-07 15:22:17

False聚合排序

2022-07-29 16:50:30

網(wǎng)絡(luò)帶寬

2021-02-01 13:35:28

微信Python技巧

2022-12-06 17:30:04

2022-05-17 07:26:33

動(dòng)畫(huà)CSS前端

2023-07-03 16:49:47

5G

2022-01-04 06:56:43

面試Java方法重載

2022-02-28 08:17:24

重載函數(shù)JS前端

2009-07-31 16:00:30

C#函數(shù)重載

2010-01-18 16:56:30

C++函數(shù)

2021-03-03 06:39:05

Nodejs前端開(kāi)發(fā)

2013-09-18 10:44:01

搜狗輸入法詞語(yǔ)
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 欧美aⅴ | 精品一区国产 | 日本在线综合 | 一区二区三区视频在线观看 | 亚洲国产精品久久人人爱 | 久草精品视频 | 欧美日韩国产精品一区二区 | 国产91亚洲精品一区二区三区 | 久久精品国产一区二区电影 | 免费观看黄a一级视频 | 国产成人精品一区二区三 | 日韩久草 | 看片天堂 | 欧美日韩在线一区二区 | 99这里只有精品视频 | 国产一区二区影院 | 黄色一级电影免费观看 | 欧美日韩理论 | 日本在线看片 | 日日久 | 亚洲午夜视频在线观看 | 精精国产xxxx视频在线播放 | 日本视频中文字幕 | 久久亚洲欧美日韩精品专区 | 无码日韩精品一区二区免费 | 欧美日韩精品一区 | 亚洲成人一区 | 亚洲成人国产精品 | 另类二区 | 涩爱av一区二区三区 | 成人欧美一区二区 | 国产精品电影在线观看 | 亚洲二区视频 | 亚洲婷婷一区 | 在线观看午夜视频 | 五月天婷婷激情 | 九色 在线 | 精品久久久久久亚洲综合网 | 五月激情婷婷网 | 亚洲成人精品国产 | 综合久 |