<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          TypeScript 中的泛型你真搞懂了嗎?

          共 3389字,需瀏覽 7分鐘

           ·

          2021-11-04 21:36

          點(diǎn)擊上方?程序員成長(zhǎng)指北,關(guān)注公眾號(hào)

          回復(fù)1,加入高級(jí)Node交流群

          在學(xué)習(xí)ts源碼的時(shí)候,發(fā)現(xiàn)很多泛型還是看不懂,于是想寫一篇文章,總結(jié)一下常用的泛型。

          基礎(chǔ)必備知識(shí)

          聯(lián)合類型vs交叉類型

          //?聯(lián)合類型
          interface?Bird?{
          ??name:?string;
          ??fly():?void;
          }
          interface?Person?{
          ??name:?string;
          ??talk():?void;
          }
          type?BirdPerson?=?Bird?|?Person;
          let?p:?BirdPerson?=?{?name:?"zfeng",?fly()?{}?};?
          let?p1:?BirdPerson?=?{?name:?"zfeng",?talk()?{}?};

          聯(lián)合類型使用 “|”表示或的關(guān)系, 滿足其中的一個(gè)情況即可。

          interface?Bird?{
          ??name:?string;
          ??fly():?void;
          }
          interface?Person?{
          ??name:?string;
          ??talk():?void;
          }
          type?BirdPerson?=?Bird?&?Person;
          let?p:?BirdPerson?=?{?name:?"zhufeng",?fly()?{},?talk()?{}?};

          交叉類型使用“&”,表示與的關(guān)系,需要滿足所有的情況。

          內(nèi)置條件類型

          type?Extract?=?T?extends?U???T?:?never;
          type?Exclude?=?T?extends?U???never?:?T;
          type?NonNullable?=?T?extends?null?|?undefined???never?:?T;

          type?N?=?NonNullable<string?|?number?|?null?|?undefined>;//?刪除null和undifined;
          type?E?=?Exclude<string?|?number,?string>;?//?排除關(guān)系?輸出?string;
          type?I?=?Extract<string?|?number,?string>;?//?包含關(guān)系?輸出?number;

          函數(shù)的類型推斷

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

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

          function?getUserInfo(name:?string,?age:?number)?{
          ??return?{?name,?age?};
          }
          type?UserInfo?=?ReturnType<typeof?getUserInfo>;

          const?userA:?UserInfo?=?{
          ??name:?"zhufeng",
          ??age:?10,
          };

          獲取函數(shù)參數(shù)的類型

          type?Parameters?=?T?extends?(...args:?infer?R)?=>?any???R?:?any;
          function?getUserInfo(name:?string,?age:?number)?{
          ??return?{?name,?age?};
          }
          type?T1?=?Parameters<typeof?getUserInfo>;??//?[name:?string,?age:?number]


          泛型進(jìn)階

          很多人對(duì)于泛型的理解還停留在基礎(chǔ)的層面,我講站在集合的視角去理解一下什么叫泛型。

          案例一:字段的提取

          給定一個(gè)接口 Persion, ?里面有name,age,visiable,三個(gè)字段,現(xiàn)在的要求是:得到一個(gè)新的接口,里面只有name,age。一般人常見的思路:

          interface?Person?{
          ??name:?string;
          ??age:?number;
          ??visiable:?boolean;
          }

          interface?Person1?{
          ??name:?string;
          ??age:?number;
          }

          我們從寫一個(gè)接口,就可以達(dá)到要求。但是這樣子的寫法,顯得十分冗余。其實(shí)ts提供了方法,讓我們可以實(shí)現(xiàn),讓我們一起看一下的例子。

          方式一:Pick 提取字段

          //?pick?的原理
          //?type?Pick?=?{?[P?in?K]:?T[P]?};
          interface?Person?{
          ??name:?string;
          ??age:?number;
          ??visiable:?boolean;
          }
          type?Person1?=?Pick'name'|'age'>?;

          Person1 就包含 name,age 字段。

          方式二:Omit 反向獲取

          interface?Person?{
          ??name:?string;
          ??age:?number;
          ??visiable:?boolean;
          }
          type?Exclude?=?T?extends?U???never?:?T;
          type?Omitextends?keyof?T>?=?Pick>;
          type?Person2?=?Omit"age">;

          案例二:兩個(gè)接口的操作

          我們把一個(gè)接口當(dāng)作一個(gè)集合,那么兩個(gè)集合的操作主要有:并集,交集,差集。

          交集

          type?Extract?=?T?extends?U???T?:?never;
          type?Intersectionextends?object,?U?extends?object>?=?Pick<
          ??T,
          ??Extract?&?Extract
          >;

          type?C1?=?{?name:?string;?age:?number;?visible:?boolean?};
          type?C2?=?{?name:?string;?age:?number;?sex:?number?};

          type?C3?=?Intersection;

          交集的定義:對(duì)于給定的兩個(gè)集合,返回一個(gè)包含兩個(gè)集合中共有元素的新集合。通過Intersection實(shí)現(xiàn)交集,可以獲得一個(gè)新接口,C3只包含 name.age。如上圖。

          差集

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

          type?C1?=?{?name:?string;?age:?number;?visible:?boolean?};
          type?C2?=?{?name:?string;?age:?number;?sex:?number?};

          type?C11?=?Diff;

          差集的定義:對(duì)于給定的兩個(gè)集合,返回一個(gè)包含所有存在于第一個(gè)集合且不存在于第二個(gè)集合的元素的新集合。通過Diff實(shí)現(xiàn)差集,可以獲得一個(gè)新接口,接口只有visiable。如上圖。

          并集

          并集的定義:對(duì)于給定的兩個(gè)集合,返回一個(gè)包含兩個(gè)集合中所有元素的新集合。通過Merge實(shí)現(xiàn)并集,可以獲得一個(gè)新接口,接口包含C1,C2 的所有屬性。如上圖。

          //Compute的作用是將交叉類型合并
          type?Computeextends?any>?=?A?extends?Function???A?:?{?[K?in?keyof?A]:?A[K]?};
          type?Omit?=?Pick>;
          type?Mergeextends?object,?O2?extends?object>?=?Compute>;
          type?C1C2?=?Merge;

          特殊的情況:Overwrite(覆蓋)

          type?C1?=?{?name:?string;?age:?number;?visible:?boolean?};
          type?C2?=?{?name:?string;?age:?string;?sex:?number?};

          C1,C2做merge, C1中有age,類型為number,C2中有age,類型為string,那么合并之后,age是string,還是number類型呢?

          Overwrite 泛型,解決了誰覆蓋誰的問題。

          type?C1?=?{?name:?string;?age:?number;?visible:?boolean?};
          type?C2?=?{?name:?string;?age:?string;?sex:?number?};

          type?Overwrite<
          ??T?extends?object,
          ??U?extends?object,
          ??I?=?Diff?&?Intersection
          >?=?Pick;
          ??
          type?overwrite?=?Overwrite;


          Node 社群


          我組建了一個(gè)氛圍特別好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你對(duì)Node.js學(xué)習(xí)感興趣的話(后續(xù)有計(jì)劃也可以),我們可以一起進(jìn)行Node.js相關(guān)的交流、學(xué)習(xí)、共建。下方加 考拉 好友回復(fù)「Node」即可。


          ???“分享、點(diǎn)贊在看” 支持一波??

          瀏覽 80
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  超碰免费操大逼 | 色色97 | 日本A片免费在线观看 | 做爰 视频毛片下载蜜桃视频 | 黄 色 视 频高潮 |