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

前端React?Nextjs中的TS類(lèi)型過(guò)濾實(shí)用技巧

 更新時(shí)間:2022年04月26日 09:53:42   作者:「零一」  
今天就來(lái)介紹一個(gè)在其它開(kāi)源庫(kù)中見(jiàn)到的既花里胡哨,又實(shí)用的TS類(lèi)型——TS類(lèi)型過(guò)濾,你會(huì)發(fā)現(xiàn)這些?TS騷操作真的很重要,因?yàn)樗芎芎玫貛椭阕鲮o態(tài)類(lèi)型校驗(yàn)

大家好,我是零一,相信大家在閱讀同事寫(xiě)的代碼或者優(yōu)秀的開(kāi)源庫(kù)的代碼時(shí),一定見(jiàn)過(guò)各種各樣的風(fēng)騷的TS寫(xiě)法,不花點(diǎn)時(shí)間下去根本看不懂,換作是我們,可能就直接一個(gè) any 完事了,但是真正當(dāng)項(xiàng)目體積變大后,你會(huì)發(fā)現(xiàn)這些 TS騷操作真的很重要,因?yàn)樗芎芎玫貛椭阕鲮o態(tài)類(lèi)型校驗(yàn)

自我介紹

TS類(lèi)型過(guò)濾,英文名(我自己取的)叫 FilterConditionally,這是它完整的樣子

type FilterConditionally<Source, Condition> = Pick<
  Source, 
  {
    [K in keyof Source]: Source[K] extends Condition ? K : never
  }[keyof Source]
>;

別看很復(fù)雜,其實(shí)非常有用,它可以從一個(gè)對(duì)象類(lèi)型中過(guò)濾出你想要的,比如:

interface Example {
    a: string;
    b: string; 
    c: number; 
    d: boolean; 
}
type NewType = FilterConditionally<Sample, string>
/*
	NewType 最終結(jié)果為:
	{
		a: string;
		b: string
	}
*/

相信大家已經(jīng)這個(gè)類(lèi)型的作用了,并且你們也很想讀懂它,沒(méi)關(guān)系,接下來(lái)由內(nèi)而外、一步一步地介紹,一定讓你們完全讀懂,讀不懂評(píng)論區(qū)來(lái)噴我(我說(shuō)著玩的~)

分步介紹

涉及的知識(shí)點(diǎn)比較多,怕有些不熟悉TS的同學(xué)懵逼,先來(lái)介紹其中幾個(gè)常見(jiàn)的基礎(chǔ)知識(shí)點(diǎn)

開(kāi)胃小菜

不會(huì)耽誤大家多少時(shí)間的,會(huì)的小伙伴可以直接調(diào)過(guò)

keyof

關(guān)鍵詞 keyof 的名字叫 索引類(lèi)型查詢操作符,它的作用就像它的字面意思一樣直白:xx的key值

interface Example {
  a: string;
  b: string;
  c: number;
  d: boolean;
}
type Keys = keyof Example   // 等價(jià)于 type Keys = 'a' | 'b' | 'c' | 'd'

你可以把 keyof 簡(jiǎn)單理解為 JavaScript 中的 Object.keys

in

關(guān)鍵詞 in 可以遍歷枚舉類(lèi)型,比如:

type Keys = 'a' | 'b' | 'c' | 'd'
type Obj = {
  [T in Keys]: string;  // 遍歷Keys,把每個(gè)key都賦值string類(lèi)型
}
/* 等價(jià)于 
	 type Obj = {
	   a: string;
	 	 b: string;
		 c: string;
		 d: string;
	 }
*/

你可以把 in 簡(jiǎn)單理解為 JavaScript 中 for...in 的 in 的作用

Conditional

第二個(gè)知識(shí)點(diǎn)是條件判斷,比如:

interface A {}
interface B extends A {}  // B繼承于A
// B是否繼承于A?若是,則為number類(lèi)型;若不是,則為string類(lèi)型
type C = B extends A ? number : string  // 等價(jià)于 type C = number
// A是否繼承于B?若是,則為number類(lèi)型;若不是,則為string類(lèi)型
type D = A extends B ? number : string  // 等價(jià)于 type D = string

你可以把 A extends B ? number : string 簡(jiǎn)單理解為 JavaScript 中的三元運(yùn)算符

泛型

泛型我就不多做介紹了,不太了解的小伙伴可以直接看 TS文檔——泛型

正餐開(kāi)始

剛剛介紹完"開(kāi)胃小菜",那就趁熱打鐵看一個(gè)簡(jiǎn)單的類(lèi)型

type MarkUnwantedTypesAsNever<Source, Condition> ={
  [K in keyof Source]: Source[K] extends Condition ? K : never
}

一句話介紹這個(gè)類(lèi)型的作用就是:遍歷一個(gè)對(duì)象類(lèi)型,將不想要的類(lèi)型標(biāo)記為 never

舉個(gè)例子

interface Example {
    a: string; 
    b: string; 
    c: number; 
    d: boolean; 
}
// 我只想要Example類(lèi)型中的string類(lèi)型的key,非string的就標(biāo)記為never
type MyType = MarkUnwantedTypesAsNever<Example, string>
/*
	等價(jià)于:
	type MyType = {
		a: 'a';
		b: 'b';
		c: never;
		d: never;
	}
*/

稍微講一下小細(xì)節(jié),[K in keyof Example] 遍歷了 Example 這個(gè)對(duì)象類(lèi)型,然后用條件判斷 Example[K] extends string ? K : never 給對(duì)應(yīng)的 key 值賦值,假設(shè)遍歷第一個(gè)key值為 a,那么 Example[K] = Example[a] = string,此時(shí)就是 string extends string ? 'a' : never,string 肯定是繼承于 string 的,所以才會(huì)有這樣一個(gè)結(jié)果

此時(shí)大家心頭一驚,為什么要把類(lèi)型搞成這樣??我們最后想要的結(jié)果不是要拿到一個(gè) { a:string; b:string } 的類(lèi)型嗎?別急,后面還有別的操作

再來(lái)看一個(gè)索引訪問(wèn)接口屬性的小知識(shí)點(diǎn)

type Value = {name: "zero2one"}["name"]  // 等價(jià)于 type Value = "zero2one"

你可以把它簡(jiǎn)單理解成 JavaScript 中訪問(wèn)對(duì)象某個(gè)key對(duì)應(yīng)的value

而在TS中還有另一種情況:

type Value = {
  name: "zero2one"; 
  age: 23
}["name" | "age"]
// 等價(jià)于 type Value = "zero2one" | 23

而值為 never 的 key 值是無(wú)法被訪問(wèn)到的:

type Value = {
  name: "zero2one"; 
  age: never
}["name" | "age"]
// 等價(jià)于 type Value = "zero2one"

所以接下來(lái)可以看更復(fù)雜的類(lèi)型了

type MarkUnwantedTypesAsNever<Source, Condition> ={
  [K in keyof Source]: Source[K] extends Condition ? K : never
}[keyof Source]

我們巧妙地利用 keyof 關(guān)鍵詞去遍歷訪問(wèn)所有的接口屬性

// 借用一下剛才例子的結(jié)果
type MyType = {
  	a: 'a';
		b: 'b';
		c: never;
		d: never;
}['a' | 'b' | 'c' | 'd']
/*
	等價(jià)于:
	type MyType = 'a' | 'b'
*/

到此為止,我們所做的事情就是:把目標(biāo)對(duì)象類(lèi)型中想要類(lèi)型的 key 值篩選了出來(lái)

別急別急,離成功就差一步之遙

最后登場(chǎng)的就是 Pick ,這個(gè)類(lèi)型是TS內(nèi)置的,簡(jiǎn)單了解一下它的作用

// Pick類(lèi)型的實(shí)現(xiàn)
type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
}

你可以不去詳細(xì)地讀懂它的實(shí)現(xiàn),只需要知道 Pick 的作用就是:篩選出類(lèi)型T 中指定的某些屬性

舉個(gè)簡(jiǎn)單的例子:

interface A {
  a: 1;
  b: 2;
  c: 3;
  d: 4;
}
type C = Pick<A, 'a' | 'c'>  // 等價(jià)于 type C = { a: 1; c: 3 }

是的,就是這么簡(jiǎn)單,好了可以來(lái)看最終的BOSS了

那么最后再?gòu)?Source 中篩選出對(duì)應(yīng)屬性即可,回到本文具體的例子當(dāng)中,圖中紅框中的值上文已得到為 type MyType = 'a' | 'b',那最后 Pick 一下就好了

interface Example {
	a: string;
  b: string;
  c: number;
  d: boolean;
}
// 上文得到的結(jié)果
type MyType = 'a' | 'b'
type Result = Pick<Example, MyType>  // 等價(jià)于 type Result = { a: string; b: string }
// ---- 以上等價(jià)于 ---- //
interface Example {
    a: string; 
    b: string;   
    c: number; 
    d: boolean; 
}
type NewType = FilterConditionally<Sample, string>
/*
	NewType 最終結(jié)果為:
	{
		a: string;
		b: string
	}
*/

這就是文章開(kāi)頭的結(jié)果獲取的全過(guò)程

實(shí)戰(zhàn)應(yīng)用例子

正如本文標(biāo)題所說(shuō)的,TS類(lèi)型過(guò)濾在很多優(yōu)秀的開(kāi)源庫(kù)中是非常常見(jiàn)的,比如我們熟悉的React中就是:

type ElementType<P = any> = {
	[K in keyof JSX.IntrinsicElements]: P extends JSX.IntrinsicElements[K] ? K : never
}[keyof JSX.IntrinsicElements] | ComponentType<P>;

最后

開(kāi)源庫(kù)中像TS類(lèi)型過(guò)濾這種場(chǎng)景太多太多了,希望今后大家遇到時(shí)能輕松讀懂。如果在屏幕前閱讀的你是后端,說(shuō)不定也能在后端的開(kāi)源框架源碼中看到它的身影呢~

以上就是前端React Nextjs中的TS類(lèi)型過(guò)濾實(shí)用技巧的詳細(xì)內(nèi)容,更多關(guān)于前端React Nextjs中的TS類(lèi)型過(guò)濾的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JS簡(jiǎn)單實(shí)現(xiàn)動(dòng)態(tài)添加HTML標(biāo)記的方法示例

    JS簡(jiǎn)單實(shí)現(xiàn)動(dòng)態(tài)添加HTML標(biāo)記的方法示例

    這篇文章主要介紹了JS簡(jiǎn)單實(shí)現(xiàn)動(dòng)態(tài)添加HTML標(biāo)記的方法,結(jié)合實(shí)例形式分析了JavaScript使用createElement()方法針對(duì)頁(yè)面元素進(jìn)行動(dòng)態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2018-04-04
  • IE的fireEvent方法概述及應(yīng)用

    IE的fireEvent方法概述及應(yīng)用

    IE中提供了一個(gè)fireEvent方法大概就是觸發(fā)某個(gè)事件發(fā)生的意思,以為是和onclick()一樣,看來(lái)是我自已為是了,有時(shí)間還要多看看javascript的細(xì)節(jié)啊,廣大網(wǎng)友也是啊
    2013-02-02
  • 淺析js中substring和substr的方法

    淺析js中substring和substr的方法

    這篇文章主要介紹了js中substring和substr的方法,對(duì)substring和substr的方法進(jìn)行描述和說(shuō)明,感興趣的小伙伴們可以參考一下
    2015-11-11
  • uniapp小程序底部tabbar圖標(biāo)大小設(shè)置辦法

    uniapp小程序底部tabbar圖標(biāo)大小設(shè)置辦法

    這篇文章主要給大家介紹了關(guān)于uniapp小程序底部tabbar圖標(biāo)大小設(shè)置辦法的相關(guān)資料,在使用uniapp進(jìn)行開(kāi)發(fā)時(shí),tabbar是我們使用的很頻繁的一個(gè)組件,但是在特定的平臺(tái)會(huì)有一些使用上的限制,需要的朋友可以參考下
    2023-08-08
  • Bootstrap導(dǎo)航條鼠標(biāo)懸停下拉菜單

    Bootstrap導(dǎo)航條鼠標(biāo)懸停下拉菜單

    這篇文章主要為大家詳細(xì)介紹了Bootstrap導(dǎo)航條鼠標(biāo)懸停下拉菜單,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • Javascript 浮點(diǎn)運(yùn)算的問(wèn)題分析與解決方法

    Javascript 浮點(diǎn)運(yùn)算的問(wèn)題分析與解決方法

    JavaScript 只有一種數(shù)字類(lèi)型 Number ,而且在Javascript中所有的數(shù)字都是以IEEE-754標(biāo)準(zhǔn)格式表示的。 浮點(diǎn)數(shù)的精度問(wèn)題不是JavaScript特有的,因?yàn)橛行┬?shù)以二進(jìn)制表示位數(shù)是無(wú)窮的
    2013-08-08
  • 微信公眾平臺(tái)獲取access_token的方法步驟

    微信公眾平臺(tái)獲取access_token的方法步驟

    這篇文章主要介紹了微信公眾平臺(tái)獲取access_token的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 純JS實(shí)現(xiàn)簡(jiǎn)單的日歷

    純JS實(shí)現(xiàn)簡(jiǎn)單的日歷

    這篇文章主要為大家詳細(xì)介紹了純JS實(shí)現(xiàn)簡(jiǎn)單日歷的的相關(guān)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • JavaScript實(shí)現(xiàn)彈出廣告功能

    JavaScript實(shí)現(xiàn)彈出廣告功能

    本文通過(guò)實(shí)例代碼給大家分享javascript實(shí)現(xiàn)彈出廣告功能,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-03-03
  • js獲取瀏覽器和屏幕的各種寬度高度

    js獲取瀏覽器和屏幕的各種寬度高度

    本文主要介紹了js獲取瀏覽器和屏幕的各種寬度高度的方法,具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-02-02

最新評(píng)論