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

React 中的 TS 類型過濾原來是這么做的!

開發 前端
今天就來介紹一個在其它開源庫中見到的既花里胡哨,又實用的TS類型——TS類型過濾

 相信大家在閱讀同事寫的代碼或者優秀的開源庫的代碼時,一定見過各種各樣的風騷的TS寫法,不花點時間下去根本看不懂,換作是我們,可能就直接一個 any 完事了,但是真正當項目體積變大后,你會發現這些 TS騷操作真的很重要,因為它能很好地幫助你做靜態類型校驗

今天就來介紹一個在其它開源庫中見到的既花里胡哨,又實用的TS類型——TS類型過濾

自我介紹

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

  1. type FilterConditionally<Source, Condition> = Pick<  
  2.   Source,   
  3.   {  
  4.     [K in keyof Source]: Source[K] extends Condition ? K : never  
  5.   }[keyof Source]  
  6. >

別看很復雜,其實非常有用,它可以從一個對象類型中過濾出你想要的,比如: 

  1. interface Example {  
  2.     a: string; // ✅   
  3.     b: string; // ✅    
  4.     c: number; // ❌   
  5.     d: boolean; // ❌   
  6.  
  7. type NewType = FilterConditionally<Sample, string>  
  8. /*  
  9.  NewType 最終結果為:  
  10.  {  
  11.   a: string;  
  12.   b: string 
  13.  }  
  14. */ 

相信大家已經這個類型的作用了,并且你們也很想讀懂它,沒關系,接下來由內而外、一步一步地介紹,一定讓你們完全讀懂,讀不懂評論區來噴我(我說著玩的~)

分步介紹

涉及的知識點比較多,怕有些不熟悉TS的同學懵逼,先來介紹其中幾個常見的基礎知識點

開胃小菜

不會耽誤大家多少時間的,會的小伙伴可以直接調過

keyof

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

  1. interface Example {  
  2.  a: string;  
  3.   b: string;  
  4.   c: number;  
  5.   d: boolean;  
  6.  
  7. type Keys = keyof Example   // 等價于 type Keys = 'a' | 'b' | 'c' | 'd' 

你可以把 keyof 簡單理解為 JavaScript 中的 Object.keys

in

關鍵詞 in 可以遍歷枚舉類型,比如: 

  1. type Keys = 'a' | 'b' | 'c' | 'd'  
  2. type Obj = {  
  3.   [T in Keys]: string;  // 遍歷Keys,把每個key都賦值string類型  
  4.  
  5. /* 等價于   
  6.   type Obj = {  
  7.     a: string;  
  8.     b: string;  
  9.    c: string;  
  10.    d: string;  
  11.   } 
  12.  */ 

你可以把 in 簡單理解為 JavaScript 中 for...in 的 in 的作用

Conditional

第二個知識點是條件判斷,比如: 

  1. interface A {}  
  2. interface B extends A {}  // B繼承于A  
  3. // B是否繼承于A?若是,則為number類型;若不是,則為string類型  
  4. type C = B extends A ? number : string  // 等價于 type C = number  
  5. // A是否繼承于B?若是,則為number類型;若不是,則為string類型  
  6. type D = A extends B ? number : string  // 等價于 type D = string 

你可以把 A extends B ? number : string 簡單理解為 JavaScript 中的三元運算符

泛型

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

正餐開始

剛剛介紹完"開胃小菜",那就趁熱打鐵看一個簡單的類型 

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

一句話介紹這個類型的作用就是:遍歷一個對象類型,將不想要的類型標記為 never

舉個例子🌰 

  1. interface Example {  
  2.     a: string; // ✅   
  3.     b: string; // ✅    
  4.     c: number; // ❌   
  5.     d: boolean; // ❌   
  6.  
  7. // 我只想要Example類型中的string類型的key,非string的就標記為never  
  8. type MyType = MarkUnwantedTypesAsNever<Example, string>  
  9. /*  
  10.  等價于:  
  11.  type MyType = {  
  12.   a: 'a';  
  13.   b: 'b';  
  14.   c: never;  
  15.   d: never;  
  16.  }  
  17. */ 

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

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

再來看一個索引訪問接口屬性的小知識點 

  1. type Value = {name: "zero2one"}["name"]  // 等價于 type Value = "zero2one" 

你可以把它簡單理解成 JavaScript 中訪問對象某個key對應的value

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

  1. type Value = {  
  2.   name: "zero2one";   
  3.   age: 23  
  4. }["name" | "age"]  
  5. // 等價于 type Value = "zero2one" | 23 

而值為 never 的 key 值是無法被訪問到的: 

  1. type Value = {  
  2.   name: "zero2one";   
  3.   age: never  
  4. }["name" | "age"]  
  5. // 等價于 type Value = "zero2one" 

所以接下來可以看更復雜的類型了 

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

我們巧妙地利用 keyof 關鍵詞去遍歷訪問所有的接口屬性 

  1. // 借用一下剛才例子的結果  
  2. type MyType = {  
  3.    a: 'a';  
  4.   b: 'b';  
  5.   c: never;  
  6.   d: never;  
  7. }['a' | 'b' | 'c' | 'd']  
  8. /*  
  9.  等價于:  
  10.  type MyType = 'a' | 'b'  
  11. */ 

到此為止,我們所做的事情就是:把目標對象類型中想要類型的 key 值篩選了出來

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

最后登場的就是 Pick ,這個類型是TS內置的,簡單了解一下它的作用 

  1. // Pick類型的實現  
  2. type Pick<T, K extends keyof T> = {  
  3.     [P in K]: T[P];  

你可以不去詳細地讀懂它的實現,只需要知道 Pick 的作用就是:篩選出類型T 中指定的某些屬性

舉個簡單的例子: 

  1. interface A {  
  2.   a: 1;  
  3.   b: 2;  
  4.   c: 3;  
  5.   d: 4;  
  6.  
  7. type C = Pick<A, 'a' | 'c'>  // 等價于 type C = { a: 1; c: 3 } 

是的,就是這么簡單,好了可以來看最終的BOSS了

那么最后再從 Source 中篩選出對應屬性即可,回到本文具體的例子當中,圖中紅框中的值上文已得到為 type MyType = 'a' | 'b',那最后 Pick 一下就好了 

  1. interface Example {  
  2.  a: string;  
  3.   b: string;  
  4.   c: number;  
  5.   d: boolean;  
  6.  
  7. // 上文得到的結果  
  8. type MyType = 'a' | 'b'  
  9. type Result = Pick<Example, MyType>  // 等價于 type Result = { a: string; b: string }  
  10. // ---- 以上等價于 ---- //  
  11. interface Example {  
  12.     a: string; // ✅   
  13.     b: string; // ✅    
  14.     c: number; // ❌   
  15.     d: boolean; // ❌   
  16.  
  17. type NewType = FilterConditionally<Sample, string>  
  18. /*  
  19.  NewType 最終結果為:  
  20.  {  
  21.   a: string;  
  22.   b: string  
  23.  }  
  24. */ 

這就是文章開頭的結果獲取的全過程

實戰應用例子

正如本文標題所說的,TS類型過濾在很多優秀的開源庫中是非常常見的,比如我們熟悉的React中就是: 

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

最后

開源庫中像TS類型過濾這種場景太多太多了,希望今后大家遇到時能輕松讀懂。如果在屏幕前閱讀的你是后端,說不定也能在后端的開源框架源碼中看到它的身影呢~ 

 

責任編輯:龐桂玉 來源: 前端大全
相關推薦

2023-04-09 23:25:30

Java注解元注解

2021-02-07 08:13:18

@DateTimeFo@NumberFormSpring

2015-08-05 10:50:01

Facebook緩存網頁

2024-02-21 23:03:56

代碼系統

2020-02-23 15:55:00

疫情AI人工智能

2016-02-25 10:46:33

數據排序數據處理谷歌

2019-10-08 12:32:07

運維架構技術

2013-11-27 12:40:21

鮑爾默微軟

2017-06-06 15:13:07

2022-12-14 07:32:40

InnoDBMySQL引擎

2020-06-30 08:12:32

VMwareKVMDocker

2022-08-15 08:01:00

三色標記JVM算法

2021-07-29 16:56:59

微信騰訊注冊

2025-04-03 10:39:56

2018-06-10 20:53:53

2018-07-10 10:48:00

IT程序員怪圈

2024-10-11 11:59:03

2023-06-27 11:57:24

用戶分析挖掘法ABtest

2023-07-27 13:44:19

業務用戶畫像

2017-11-01 21:33:40

python
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品国产欧美一区二区三区成人 | 欧美成人h版在线观看 | 国产成人精品一区二区三 | aaaaaaa片毛片免费观看 | 免费一区 | 久久爱黑人激情av摘花 | 欧美日韩在线精品 | 久久综合一区 | 日日综合| 国产精品精品3d动漫 | 国产福利91精品一区二区三区 | 黄色网址在线免费观看 | 日韩精品久久久 | 在线观看视频一区二区三区 | 国产精品色综合 | 中文字幕91 | 久久99视频| 天天弄| 日韩成人免费视频 | 国产精品久久久久久久久久久久久久 | 久精品久久| 亚洲电影一区二区三区 | 久草在线 | 91婷婷韩国欧美一区二区 | 亚洲图片视频一区 | 国产九一精品 | 男女精品久久 | 国产高清久久久 | 亚洲v日韩v综合v精品v | 久久久久综合 | 97精品超碰一区二区三区 | 天天久 | 国产成人精品a视频 | 日本韩国欧美在线观看 | 一本一道久久a久久精品综合 | 国产福利视频在线观看 | 在线黄av | 在线观看国产 | 日日夜夜天天 | 一区二区国产精品 | 成人一区av偷拍 |