欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

TypeScript 內(nèi)置高級(jí)類型編程示例

 更新時(shí)間:2022年09月21日 10:56:41   作者:前端西瓜哥  
這篇文章主要為大家介紹了TypeScript 內(nèi)置高級(jí)類型編程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

TypeScript 類型編程

TypeScript 的類型系統(tǒng),最基本的是簡(jiǎn)單對(duì)應(yīng) JavaScript 的 基本類型,比如 string、number、boolean 等,然后是新增的 tuple、enum、復(fù)合類型、交叉類型、索引類型等 增強(qiáng)類型。

這里會(huì)有一個(gè)問題,就是函數(shù)聲明支持不同類型的重復(fù)編寫問題,比如我的一個(gè)函數(shù)要接收一個(gè)數(shù)組,然后從中取中一個(gè)元素。

一旦我們傳入的數(shù)組類型不同,都要寫多一個(gè) type 別名,未免太繁瑣。

type getStrItem = (items: string[]) => string;
type getNumItem = (items: number[]) => number;
// ... 每增加一種類型都要寫多了一個(gè) type 別名
const getStrFirst: getStrItem = (a) => {
    return a[0];
}

為解決這個(gè)問題,TypeScript 引入了 泛型,讓類型也能成為參數(shù)了。

type getItem<T> = (items: T[]) => T
const getStrFirst: getItem<string> = (a) => {
    return a[0];
}

上面的 T 就是一個(gè)類型參數(shù),當(dāng)我們通過 類型別名<具體類型> 形式(上面代碼對(duì)應(yīng) getItem<string>),我們就能得到一個(gè)具體的類型了。

鑒于 JavaScript 太靈活,TypeScript 實(shí)現(xiàn)的是結(jié)構(gòu)類型系統(tǒng),我們又覺得泛型的簡(jiǎn)單推到 T 的粒度還是不夠細(xì),我們希望能夠獲取 T 內(nèi)部的結(jié)構(gòu)。

于是,TypeScript 在泛型的基礎(chǔ)上,又提供了 類型編程,通過一些語法,我們可以拿到 T 下更細(xì)粒度的類型,或通過判斷拿到其他類型。

這個(gè)也被大家戲稱為 類型體操??赡苁且?yàn)閷?shí)現(xiàn)起來花里胡哨像是在參加體操大賽的原因。

總結(jié)一下,從類型能力上的增強(qiáng)的過程來說,就是:

基本類型 -> 泛型 -> 類型編程(類型體操)

TypeScript 內(nèi)置高級(jí)類型

TS 代碼版本為 4.8.2

下面我們來看一下 TypeScript 內(nèi)置的幾個(gè)高級(jí)類型,它們用了類型編程。

Pick<Type, Keys>

Pick 的作用是,從 T 類型(對(duì)象類型)中,提取出 K(聯(lián)合類型)圈定的 key,返回一個(gè)新的對(duì)象類型。

這里我們通過 Pick 提取了需要的 pos 和 radius 物理信息屬性。

看看 Pick 的實(shí)現(xiàn):

/**
 * From T, pick a set of properties whose keys are in the union K
 */
type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};

首先我們看等號(hào)左側(cè)的 <T, K extends keyof T>,類型參數(shù)有兩個(gè),T 和 K。

先說類型參數(shù)命名

類型變量命名和寫 JS 變量一樣,隨意起名。但建議首字母大寫,以防止和一些關(guān)鍵字混淆(比如 extends, as, infer),這些關(guān)鍵詞都是小寫的。

T 通常代表一個(gè)要被分析的類型(Type),K 通常代表對(duì)象屬性名(Key)。就像數(shù)學(xué)中函數(shù)的 x 和 y 一樣,想不到好的命名就用這倆。

keyof 是類型運(yùn)算符,用于提取對(duì)象的屬性(key),然后拼裝成聯(lián)合類型。

extends 用于限制類型參數(shù)的范圍。比如 <T extends string> 表示 T 類型必須是 string 的子類,像字面量的 "a" 或 string 都是 string 的子類。如果不是 string 子類,編譯無法通過。

還有一種是 extends ? : 的類似 JS 中三元運(yùn)算符的語法,它在等號(hào)的右側(cè),用于實(shí)現(xiàn)條件判斷。它和前面提到的 extends 不是同一樣?xùn)|西,后面我會(huì)說到。

Ok,我們整體看看 <T, K extends keyof T> 代表什么意思。它表示傳入 T 和 K 兩個(gè)類型參數(shù),然后 K 必須是 T 的屬性組成的聯(lián)合類型中的一部分。

我們?cè)倏纯吹忍?hào)右邊 { [P in K]: T[P]; };,它是對(duì)類型進(jìn)行 重映射

in 用于對(duì)聯(lián)合類型進(jìn)行遍歷。也就是遍歷我們需要用到的 key,作為索引 P,然后它的值還是用對(duì)應(yīng)的 T[P]。

Exclude<UnionType, ExcludedMembers>

Exclude 的作用是,從聯(lián)合類型中剔除掉一些類型。

實(shí)現(xiàn)如下:

/**
 * Exclude from T those types that are assignable to U
 */
type Exclude<T, U> = T extends U ? never : T;

這里涉及到一個(gè)經(jīng)常用到的 條件語法extends ? :,你可以把它類比為 JS 中的三元表達(dá)式(即 condition ? a : b)。

為了更好的講解,我們實(shí)現(xiàn)一個(gè)類型 IsNumber,判斷一個(gè)類型是否為數(shù)值類型。

type IsNumber<T> = T extends number ? true : false;
// 使用
type A = IsNumber<1> // true
type B = IsNumber<"str"> // false

T extends number 判斷 T 是否為 number 的子類,如果是的話,返回 true,否則返回 false。

需注意和前面的類型參數(shù)上 extends 是完全不同的東西。

回到我們的 Exclude,邏輯就很清楚了,就是判斷 T 是否為 U 的子類,如果是的話,返回 never(效果是被丟棄);否則返回 T。

你是不是有點(diǎn)奇怪結(jié)果,邏輯看起來不應(yīng)該是 "a" | "b" | "c" 不是 "b" 的子類,返回 "a" | "b" | "c" 嗎?怎么編程了 "a" | "c"?

其實(shí)這是聯(lián)合類型的特殊邏輯,如果聯(lián)合類型使用了 extends,它就會(huì)被打散,變成多個(gè)獨(dú)立的類型進(jìn)行判斷,最后再組合起來。

所以真正邏輯是, "a" | "b" | "c" 被打散,變成依次判斷 "a" 、"b"、"c" 是否為 "b" 的子類,分別得到  "a" 、never、"c",然后聯(lián)合起來,就變成了  "a" | "c"。

ReturnType<Type>

獲取函數(shù)類型的返回值類型。

實(shí)現(xiàn)為:

/**
 * Obtain the return type of a function type
 */
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

等號(hào)左側(cè)的 (...args: any) => any 代表一個(gè)任意函數(shù)類型,用于限制傳入?yún)?shù)的類型。

然后我們看到了一個(gè)新的關(guān)鍵詞 infer,代表引用的意思,用于類型推導(dǎo)。

extends 和 infer 搭配,可以實(shí)現(xiàn) 模式匹配,如果 extends 匹配成功,infer 就能推導(dǎo)獲得對(duì)應(yīng)的類型。

如果你了解  JS 的正則表達(dá)式,你會(huì)發(fā)現(xiàn)它們很像,infer 好比是捕獲組。

'ABC'.replace(/A(.)C/, '$1') 
// 'B'。提取了模式上匹配的一個(gè)字符串

T extends (...args: any) => infer R ? R : any; 中,我們給返回值部分設(shè)置了 infer,并提供了一個(gè)局部變量 R。

如果 extends 條件判斷是繼承關(guān)系,那么變量 R 就會(huì)被賦值函數(shù)的返回值。

后面的判斷為真的分支(? 后面的表達(dá)式)就能拿到這個(gè) R。判斷為假的分支就無法拿到,因?yàn)槠ヅ涫×恕?/p>

這個(gè) extends + infer 其實(shí)就是類型體操的精髓,可以在傳入類型 T 繼續(xù)拆分,拿到更細(xì)粒度的類型。

更多類型體操學(xué)習(xí)

還有更多的類型編程的技巧因?yàn)槠蚓筒徽f了,比如還有:

  • as 運(yùn)算符可以做類型索引的重映射;
  • 通過數(shù)組的 "length" 可以實(shí)現(xiàn)數(shù)字運(yùn)算;
  • 通過遞歸實(shí)現(xiàn)循環(huán)邏輯;
  • 一些特殊的類型(比如 never)的處理等。

TypeScript 的類型是圖靈完備的,可以實(shí)現(xiàn)各種判斷、循環(huán)、加減的邏輯。當(dāng)然某些邏輯實(shí)現(xiàn)起來很繁瑣就是了。

它的語法也是與眾不同:它做了 “壓縮”。一個(gè)類型的編程只是一個(gè)表達(dá)式,需要用 extend ? : 的方式不停嵌套實(shí)現(xiàn)邏輯。TS 類型體操學(xué)起來,某種意義上確實(shí)有點(diǎn)像學(xué)一門新的語言,而且有那么一點(diǎn)古怪。

以上就是TypeScript 內(nèi)置高級(jí)類型編程示例的詳細(xì)內(nèi)容,更多關(guān)于TypeScript 內(nèi)置類型的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 微信小程序promsie.all和promise順序執(zhí)行

    微信小程序promsie.all和promise順序執(zhí)行

    這篇文章主要介紹了微信小程序promsie.all和promise順序執(zhí)行的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-10-10
  • 一文解析Express框架view對(duì)象使用

    一文解析Express框架view對(duì)象使用

    這篇文章主要介紹了Express框架view對(duì)象使用解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 微信小程序 生命周期和頁面的生命周期詳細(xì)介紹

    微信小程序 生命周期和頁面的生命周期詳細(xì)介紹

    這篇文章主要介紹了微信小程序 生命周期和頁面的生命周期詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • TypeScript新語法之infer?extends示例詳解

    TypeScript新語法之infer?extends示例詳解

    這篇文章主要為大家介紹了TypeScript新語法之infer?extends示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • 詳解微信小程序 相對(duì)定位和絕對(duì)定位

    詳解微信小程序 相對(duì)定位和絕對(duì)定位

    這篇文章主要介紹了詳解微信小程序 相對(duì)定位和絕對(duì)定位的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • 微信小程序?qū)崿F(xiàn)頁面跳轉(zhuǎn)傳值的方法

    微信小程序?qū)崿F(xiàn)頁面跳轉(zhuǎn)傳值的方法

    這篇文章主要介紹了微信小程序?qū)崿F(xiàn)頁面跳轉(zhuǎn)傳值的方法的相關(guān)資料,希望通過本文能幫助到大家,讓大家實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下
    2017-10-10
  • JavaScript+HTML實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)

    JavaScript+HTML實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)

    這篇文章主要介紹了JavaScript實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)js的小伙伴們有一定的幫助,需要的朋友可以參考下
    2021-04-04
  • 微信小程序 使用騰訊地圖SDK詳解及實(shí)現(xiàn)步驟

    微信小程序 使用騰訊地圖SDK詳解及實(shí)現(xiàn)步驟

    這篇文章主要介紹了微信小程序 使用騰訊地圖SDK詳解及實(shí)現(xiàn)步驟的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • 最新評(píng)論