<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      TypeScript(十一)泛型工具類型

      目錄

      前言

      Partial

      Required

      Readonly

      Pick,>

      Exclude,>

      Omit,>

      Record,>

      NonNullable

      ReturnType

      Parameters

      ConstructorParameters

      InstanceType

      ThisParameterType

      OmitThisParameter

      寫在最后

      相關文章


      前言

      本文收錄于TypeScript知識總結系列文章,歡迎指正! 

      前面的文章我們對泛型的用法有了大概的認識,也通過泛型實現了一些常用的類型,那么這篇文章將帶各位深入了解一些常用泛型工具類型的使用及實現,那么話不多說,我們直接開始。

      Partial<T>

      Partial<T>的作用是將類型T中的所有屬性變為可選屬性

      interface IAnimal {
          name: string
          age: number
          color: string
      }
      type MyPartial = Partial<IAnimal>

      相當于轉換成了

      type MyPartial = {
          name?: string;
          age?: number;
          color?: string;
      }

      它的實現是使用映射類型對對象屬性遍歷 

      type Partial<T> = {
          [P in keyof T]?: T[P];
      };

      Required<T>

      Required與Partial相反,作用是將所有屬性變成必選屬性,用到的原理就是 '-?' 符號

      type MyRequired = Required<MyPartial>

      上面的代碼中的MyRequired變回了IAnimal,以下是Required的實現

      type Required<T> = {
          [P in keyof T]-?: T[P];
      };

      Readonly<T>

      只讀屬性我們在前面的文章也提及過,將所有的屬性換成只讀

      type MyReadonly = Readonly<MyRequired>
      type Readonly<T> = {
          readonly [P in keyof T]: T[P];
      };

      Pick<T, K>

      Pick的作用是在對象中選取一部分屬性,比如我們選取name和age

      type MyPick = Pick<IAnimal, "name" | "age">

      他的實現過程是傳入兩個類型參數,第一個是對象類型,第二個是屬性集合

      type Pick<T, K extends keyof T> = {
          [P in K]: T[P];
      };

      Exclude<T, U>

      Exclude<T, U>表示從T中排除U類型或類型集合,如下面代碼排除了string類型

      type MyExclude = Exclude<string | number | boolean, string>

      此外,我們可以將Exclude融入對象類型,針對屬性值進行排除,如

      type ExcludeAnimal = {
          [key in Exclude<keyof IAnimal, string>]: IAnimal[key]
      }

      上述代碼實現的是將IAnimal中字符類型屬性名全部排除,也就是將屬性全清除

      Exclude的實現

      type Exclude<T, U> = T extends U ? never : T;

      Omit<T, K>

      Omit<T, K>的含義是從T對象類型中刪除K,比如我們可以刪除IAnimal的age和color

      type OmitAnimal = Omit<IAnimal, "age" | "color">

      它的實現方式也是通過Pick+Exclude實現的,僅需記住兩步:Exclude排除T中K的類型,返回值傳給Pick;使用Pick生成新的對象類型

      type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

      Record<K, T>

      Record可以理解為批量創建一個對象中的屬性,其中鍵值或其集合是K,類型是T。我們使用Record表示一下上面的IAnimal

      type RecordAnimal = Record<"name" | "color", string> & Record<"age", number>

      實現方式如下,其中P是K的子集代表著對象的屬性

      type Record<K extends keyof any, T> = {
          [P in K]: T;
      };

      上面的代碼實際上我們可以這么寫,通過string | number | symbol集合保證key的安全

      type IRecord<K extends string | number | symbol, T> = { [key in K]: T }

      NonNullable<T>

      NonNullable<T>一般用來從類型T中排除空類型,即判斷是否存在null或undefined,如果不是則返回原類型

      NonNullable<null | undefined | string | boolean | number> // 表示 string | number | boolean

      類型實現

      type NonNullable<T> = T extends null | undefined ? never : T;

      ReturnType<T>

      ReturnType是用來獲取函數的返回值類型,其中T表示函數類型

      type foo<T> = (params: T) => T[]
      type IReturnType = ReturnType<foo<string>>

      當函數并未調用時,我們無法獲得泛型的類型,此時使用ReturnType則會獲得unknown類型

      function foo<T>(params: T) {
          return [params]
      }
      type IReturnType = ReturnType<typeof foo> // unknown[]

      ReturnType的實現就需要使用到我們前面文章說到的infer關鍵字了

      我們復習一下返回函數的返回值類型是怎么實現的?

      type IReturn<T> = T extends (...args: any[]) => infer R ? R : T;
      type foo = () => string
      type IReturnType = IReturn<foo>// string

      然后我們給泛型加個約束,泛型只能傳入函數類型

      type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

      這樣,一個獲取函數返回值的類型就實現完成了

      Parameters<T>

      說完了獲取函數返回值類型,咱們看看Parameters<T>獲取函數參數類型,通過傳入函數T來獲取T的參數類型

      type foo<T> = (params: T) => T
      type IGetParameters = Parameters<foo<string>>// [params: string]

      參數類型像arguments數組一樣,思考以下代碼,使用infer實現獲取函數參數類型

      type IParameters<T> = T extends (...args: infer P) => any ? P : T;

      與函數返回值一樣,通過添加一個函數的約束來實現完整功能

      type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;

      ConstructorParameters<T>

      ConstructorParameters表示獲取構造函數T的參數類型,我們使用接口定義一個類的構造函數,并通過ConstructorParameters獲取其參數的偽數組

      interface IAnimal {
          new(name: string, age: number)
      }
      type getConstructorParameters = ConstructorParameters<IAnimal> // [name: string, age: number]

      實現方式與Parameters類似,只不過把函數類型換成了類

      type IConstructorParameters<T> = T extends new (...args: infer P) => any ? P : never;

      tips:官方的對此類型的實現中有個巧妙的地方:使用抽象類實現了該類型。原因是什么?我們看看下面的代碼

      // 抽象類
      abstract class Animal { }
      
      // 類
      class Dog { }
      
      // 使用類類型實現獲取構造函數參數類型
      type ICParameters<T> = T extends new (...args: infer P) => any ? P : never;
      
      // 使用抽象類類型實現獲取構造函數參數類型
      type IAbstractCParameters<T> = T extends abstract new (...args: infer P) => any ? P : never;
      
      // 抽象類類型-抽象類
      type getAbstractCParametersAnimal = IAbstractCParameters<typeof Animal>// []
      
      // 抽象類類型-類
      type getAbstractCParametersDog = IAbstractCParameters<typeof Dog>// []
      
      // 類類型-抽象類
      type getCParametersAnimal = ICParameters<typeof Animal>// never
      
      // 類類型-類
      type getCParametersDog = ICParameters<typeof Dog>// []

      可以看到由于抽象類只能被類繼承,而不能反過來繼承類,還記得之前講述的關于類的文章嗎?抽象類只能被繼承,不能被實例化,并且只能被類或者抽象類繼承。所以理解為使用抽象類實現獲取構造函數參數類型可以運用于抽象類,而使用類實現獲取構造函數參數類型無法運用于抽象類。描述的比較亂,僅供參考,具體看看代碼會清晰一點

      最后在上述的基礎上給ConstructorParameters類型增加一個抽象類的約束就可以通過以下代碼實現完整類型了

      type ConstructorParameters<T extends abstract new (...args: any) => any> = T extends abstract new (...args: infer P) => any ? P : never;

      InstanceType<T>

      InstanceType用于獲取類的實例化類型,即 new 類 的產物,可以說是執行構造函數的返回值,與上面的ConstructorParameters類型相對應

      class Animal {
          constructor(name?: string, age?: number) { }
      }
      const animal: InstanceType<typeof Animal> = new Animal()

      實現方式也類似,就不多做描述

      type InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;

      ThisParameterType<T>

      ThisParameterType獲取函數參數的this的類型,常常用在call,apply,bind中。

      function getThis(this: any) {
          console.log(this);
      }
      type getThisType = ThisParameterType<typeof getThis>;// string

      但同時,只要函數內部的第一個參數不命名為this,這個類型就表示unknown

      function getThis(str: string) {
          console.log(str);
      }
      type getThisType = ThisParameterType<typeof getThis>;// unknown

      tips:編譯后的函數第一個參數會消失

      function getThis() {
          console.log(this);
      }

      實現方式是獲取函數的第一個為this參數的類型

      type ThisParameterType<T> = T extends (this: infer U, ...args: never) => any ? U : unknown;

      OmitThisParameter<T>

      OmitThisParameter的用途是若函數的第一個參數為this,則將其刪除并返回函數類型

      function getThis(this: string) {
          console.log(this);
      }
      type getThisType = OmitThisParameter<typeof getThis>;// () => void

      其實現方式如下

      type OmitThisParameter<T> = T extends (this: any, ...args: infer P) => infer R ? (...args: P) => R : T;

      寫在最后

      以上就是文章全部內容了,本篇文章針對泛型常用的工具類型做了詳細的解讀及實現,有什么問題還望多多指教,感謝你看到了最后,如果文章對你有幫助,還望支持一下,謝謝!

      相關文章

      TypeScript/es5.d.ts at main · microsoft/TypeScript · GitHub

      posted @ 2023-04-09 19:39  阿宇的編程之旅  閱讀(129)  評論(0)    收藏  舉報  來源
      主站蜘蛛池模板: 国产极品嫩模在线观看91| 无码抽搐高潮喷水流白浆| 999精品全免费观看视频| 久久大香萑太香蕉av黄软件 | 国产一区精品综亚洲av| 中文人妻av高清一区二区| 久久午夜夜伦鲁鲁片免费无码影院 | 久久久久久亚洲精品成人| 在线日韩日本国产亚洲| 天天躁夜夜踩很很踩2022| 在线看片免费人成视频久网| 2020国产欧洲精品网站| 久久波多野结衣av| 亚洲无人区码一二三四区| 无码日韩精品一区二区三区免费| 最新的国产成人精品2020| 国产卡一卡二卡三免费入口| 亚洲乱熟乱熟女一区二区| 无码人妻斩一区二区三区 | 国产卡一卡二卡三免费入口| 国产极品粉嫩学生一线天| 激情久久av一区二区三区| 99久久国产综合精品女同| 国产又色又爽又黄的在线观看| 国产精品一区二区久久毛片| 免费AV片在线观看网址| 99国产欧美久久久精品蜜芽| 亚洲日韩成人无码不卡网站| 日韩精品一区二区三区久| 亚洲国产成人无码影院| 枞阳县| 亚洲综合国产成人丁香五| 日韩av毛片福利国产福利| 九九久久精品国产免费看小说| 衡阳市| 国产成人精品久久性色av| 少妇粗大进出白浆嘿嘿视频| 成人国产精品中文字幕| 蜜臀av性久久久久蜜臀aⅴ麻豆 | 最新国产精品中文字幕| 91久久偷偷做嫩草影院免费看|