TypeScript類型編程中的extends和infer示例解析
引文
在剛接觸TypeScript的時(shí)候,使用最多的就是type和interface這兩個(gè)關(guān)鍵字,用來(lái)聲明類型,其實(shí)這樣也基本滿足日常需求。但是如果需要設(shè)計(jì)一些高級(jí)類型的話,那么僅僅用原來(lái)所掌握的TypeScript知識(shí)是無(wú)法滿足需求的。
設(shè)計(jì)高級(jí)類型的話涉及到類型編程的知識(shí)點(diǎn),而類型編程中有兩個(gè)關(guān)鍵字非常重要,分別是extends和infer。
extends用來(lái)約束入?yún)⒌念愋鸵约斑M(jìn)行條件判斷,infer用來(lái)聲明局部的類型變量。
extends
條件判斷
我們舉個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明
type isOne<T extends number> = T extends 1 ? true : false
我們單獨(dú)看T extends 1 ? true : false
這部分,這里和JavaScript
中的三元表達(dá)式并無(wú)二致,但是有些同學(xué)不清楚其中extends表示的是什么含義。
T extends 1 ? true : false表示的含義其實(shí)就是傳入的T類型是否能夠賦值給字面量1這個(gè)類型,如果可以的話,就返回true,否則返回false
約束參數(shù)類型
繼續(xù)使用上面的例子,我們單獨(dú)看T extends number
,這里extends的意思就是限制傳入的T類型必須是number類型,否則報(bào)錯(cuò)。
為什么需要有這個(gè)限制?
因?yàn)槲覀兪且袛囝愋蚑是否能夠賦值給字面量類型1,但是如果傳入的參數(shù)都不是number類型,那么就沒(méi)必要做后續(xù)的條件判斷了。
約束infer推導(dǎo)的局部變量類型
type GetFirst<T extends string[]> = T extends [infer FirstChar, ...infer Rest] ? `${FirstChar}` : never; type Res = GetFirst<['1', '2', '3']>;
來(lái)看看報(bào)錯(cuò)信息,我們傳入的參數(shù)類型限制為sting類型的數(shù)組,但是infer推導(dǎo)出來(lái)的類型實(shí)際上是unknown類型,所以導(dǎo)致類型不匹配。
解決辦法有三種:
對(duì)FirstChar使用extends先做過(guò)濾
type GetFirst<T extends string[]> = T extends [infer FirstChar, ...infer Rest] ? FirstChar extends string ? `${FirstChar}` : never : never;
FirstChar和string進(jìn)行交叉運(yùn)算
type GetFirst<T extends string[]> = T extends [infer FirstChar, ...infer Rest] ? `${FirstChar & string}` : never;
使用infer extends做類型轉(zhuǎn)換
type GetFirst<T extends string[]> = T extends [ infer FirstChar extends string, ...infer Rest ] ? `${FirstChar}` : never;
infer extends
是在ts 4.7版本支持,低于這個(gè)版本無(wú)法使用。
類型轉(zhuǎn)換
type StrToNum<T extends string> = T extends `${infer Num extends number}` ? Num : T type Res = StrToNum<"1"> // ts 4.7時(shí),返回的結(jié)果是type Res = number // ts 4.8及以上, 返回的結(jié)果是type Res = 1
infer
還是拿例子來(lái)進(jìn)行講解,下面的例子是要提取Promise包裹的類型。
type PromiseValue<T extends Promise<unknown>> = T extends Promise<infer Value> ? Value : never type Res = PromiseValue<Promise<string>> // string
畫個(gè)簡(jiǎn)單的圖來(lái)描述下如何提取變量類型。
注意:infer聲明的局部變量,只能在條件語(yǔ)句為true的分支里面使用。
如果在false分之里面使用通過(guò)infer聲明的局部變量,編譯器會(huì)直接報(bào)錯(cuò)表示找不到這個(gè)變量。
組合使用
ReturnType
內(nèi)置工具類型RetureType用于獲取函數(shù)的返回值類型。
type MyReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any; type Res = MyReturnType<() => string> // type Res = string
Parameters
內(nèi)置工具類型Parameters用于獲取函數(shù)的參數(shù)類型。
type MyParameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never; type Res = MyParameters<(a: string, b: number) => void> // type Res = [a: string, b: number]
以上就是TypeScript類型編程中的extends和infer示例解析的詳細(xì)內(nèi)容,更多關(guān)于TypeScript類型編程extends infer的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
ts?類型體操?Chainable?Options?可鏈?zhǔn)竭x項(xiàng)示例詳解
這篇文章主要為大家介紹了ts?類型體操?Chainable?Options?可鏈?zhǔn)竭x項(xiàng)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09簡(jiǎn)單三行代碼函數(shù)實(shí)現(xiàn)幾十行Typescript類型推導(dǎo)
這篇文章主要為大家介紹了簡(jiǎn)單三行代碼函數(shù)實(shí)現(xiàn)幾十行Typescript類型推導(dǎo)的方案示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01typescript快速上手的基礎(chǔ)知識(shí)篇
靜態(tài)類型的typescript與傳統(tǒng)動(dòng)態(tài)弱類型語(yǔ)言javascript不同,在執(zhí)行前會(huì)先編譯成javascript,因?yàn)樗鼜?qiáng)大的type類型系統(tǒng)加持,能讓我們?cè)诰帉懘a時(shí)增加更多嚴(yán)謹(jǐn)?shù)南拗?。注意,它并不是一門全新的語(yǔ)言,所以并沒(méi)有增加額外的學(xué)習(xí)成本2022-12-12jsf實(shí)現(xiàn)微信小程序簡(jiǎn)潔登錄頁(yè)面(附源碼)
這篇文章主要介紹了實(shí)現(xiàn)微信小程序簡(jiǎn)潔登錄頁(yè)面?,對(duì)于正在學(xué)習(xí)的小伙伴都有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-01-01TypeScript開發(fā)HapiJS應(yīng)用詳解
這篇文章主要為大家介紹了TypeScript開發(fā)HapiJS應(yīng)用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08typescript快速上手的進(jìn)階類型與技術(shù)
本文講述了typescript開發(fā)的一些高級(jí)的類型與技術(shù),算是對(duì)于基礎(chǔ)知識(shí)點(diǎn)的補(bǔ)充,具體內(nèi)容包括:比如元組、枚舉類、接口、泛型相關(guān)概念等。雖說(shuō)是進(jìn)階,但是內(nèi)容不算多也并不難理解。2022-12-12Typescript是必須要學(xué)習(xí)嗎?如何學(xué)習(xí)TS全棧開發(fā)
Typescript目前在前端,網(wǎng)站,小程序中的位置基本無(wú)可替代,同時(shí)也可以構(gòu)建完美的CLI應(yīng)用。在移動(dòng),桌面,后端方面,性能不是要求很高的情況下完全可以勝任,并且在區(qū)塊鏈,嵌入式,人工智能方面也開始茁壯成長(zhǎng)。2022-12-12