<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>

          用了 TS 映射類(lèi)型,同事直呼內(nèi)行!

          共 2754字,需瀏覽 6分鐘

           ·

          2022-05-28 13:26

          在日常工作中,用戶注冊(cè)是一個(gè)很常見(jiàn)的場(chǎng)景。這里我們可以使用 TS 定義一個(gè) User 類(lèi)型,在該類(lèi)型中所有的鍵都是必填的。

          type?User?=?{
          ??name:?string;?//?姓名
          ??password:?string;?//?密碼
          ??address:?string;?//?地址
          ??phone:?string;?//?聯(lián)系電話
          };

          通常情況下,對(duì)于已注冊(cè)的用戶,我們是允許用戶只修改部分用戶信息。這時(shí)我們就可以定義一個(gè)新的 UserPartial 類(lèi)型,表示用于更新的用戶對(duì)象的類(lèi)型,在該類(lèi)型中所有的鍵都是可選的。

          type?UserPartial?=?{
          ??name?:?string;?//?姓名
          ??password?:?string;?//?密碼
          ??address?:?string;?//?地址
          ??phone?:?string;?//?聯(lián)系電話
          };

          而對(duì)于查看用戶信息的場(chǎng)景,我們希望該用戶對(duì)象所對(duì)應(yīng)的對(duì)象類(lèi)型中所有的鍵都是只讀。針對(duì)這種需求,我們可以定義 ReadonlyUser 類(lèi)型。

          type?ReadonlyUser?=?{
          ??readonly?name:?string;?//?姓名
          ??readonly?password:?string;?//?密碼
          ??readonly?address:?string;?//?地址
          ??readonly?phone:?string;?//?聯(lián)系電話
          };

          回顧前面已定義的與用戶相關(guān)的 3 種類(lèi)型,你會(huì)發(fā)現(xiàn)它們中含有很多重復(fù)的代碼。

          那么如何減少以上類(lèi)型中的重復(fù)代碼呢?答案是可以使用映射類(lèi)型,它是一種泛型類(lèi)型,可用于把原有的對(duì)象類(lèi)型映射成新的對(duì)象類(lèi)型。


          映射類(lèi)型的語(yǔ)法如下:

          {?[?P?in?K?]?:?T?}

          其中 P in K 類(lèi)似于 JavaScript 中的?for...in?語(yǔ)句,用于遍歷 K 類(lèi)型中的所有類(lèi)型,而 T 類(lèi)型變量用于表示 TS 中的任意類(lèi)型。

          在映射的過(guò)程中,你還可以使用?readonly?和???這兩個(gè)額外的修飾符。通過(guò)添加?+??-?前綴,來(lái)增加和移除對(duì)應(yīng)的修飾符。如果沒(méi)有添加任何前綴的話,默認(rèn)是使用?+。

          現(xiàn)在我們就可以總結(jié)出常見(jiàn)的映射類(lèi)型語(yǔ)法:

          {?[?P?in?K?]?:?T?}
          {?[?P?in?K?]??:?T?}
          {?[?P?in?K?]?-?:?T?}
          {?readonly?[?P?in?K?]?:?T?}
          {?readonly?[?P?in?K?]??:?T?}
          {?-readonly?[?P?in?K?]??:?T?}

          介紹完映射類(lèi)型的語(yǔ)法,我們來(lái)看一些具體的例子:

          type?Item?=?{?a:?string;?b:?number;?c:?boolean?};

          type?T1?=?{?[P?in?"x"?|?"y"]:?number?};?//?{?x:?number,?y:?number?}
          type?T2?=?{?[P?in?"x"?|?"y"]:?P?};?//?{?x:?"x",?y:?"y"?}
          type?T3?=?{?[P?in?"a"?|?"b"]:?Item[P]?};?//?{?a:?string,?b:?number?}
          type?T4?=?{?[P?in?keyof?Item]:?Item[P]?};?//?{?a:?string,?b:?number,?c:?boolean?}

          下面我們來(lái)看一下如何利用映射類(lèi)型來(lái)重新定義 UserPartial 類(lèi)型:

          type?MyPartial?=?{
          ??[P?in?keyof?T]?:?T[P];
          };

          type?UserPartial?=?MyPartial;

          在以上代碼中,我們定義了 MyPartial 映射類(lèi)型,然后利用該類(lèi)型把 User 類(lèi)型映射成 UserPartial 類(lèi)型。

          其中 keyof 操作符用于獲取某種類(lèi)型中的所有鍵,其返回類(lèi)型是聯(lián)合類(lèi)型。而類(lèi)型變量 P 會(huì)隨著每次遍歷改變成不同的類(lèi)型,T[P]?該語(yǔ)法類(lèi)似于屬性訪問(wèn)的語(yǔ)法,用于獲取對(duì)象類(lèi)型某個(gè)屬性對(duì)應(yīng)值的類(lèi)型。

          TypeScript 4.1 版本允許我們使用?as 子句對(duì)映射類(lèi)型中的鍵進(jìn)行重新映射。它的語(yǔ)法如下:

          type?MappedTypeWithNewKeys?=?{
          ????[K?in?keyof?T?as?NewKeyType]:?T[K]
          ????//????????????^^^^^^^^^^^^^
          ????//????????????這是新的語(yǔ)法!
          }

          其中 NewKeyType 的類(lèi)型必須是?string | number | symbol?聯(lián)合類(lèi)型的子類(lèi)型。使用 as 子句,我們可以定義一個(gè) Getters 工具類(lèi)型,用于為對(duì)象類(lèi)型生成對(duì)應(yīng)的 Getter 類(lèi)型:

          type?Getters?=?{
          ??[K?in?keyof?T?as?`get${Capitalize<string?&?K>}`]:?()?=>?T[K]
          };

          interface?Person?{
          ????name:?string;
          ????age:?number;
          ????location:?string;
          }

          type?LazyPerson?=?Getters;
          //?{
          //???getName:?()?=>?string;
          //???getAge:?()?=>?number;
          //???getLocation:?()?=>?string;
          //?}

          在以上代碼中,因?yàn)?keyof ?T 返回的類(lèi)型可能會(huì)包含 symbol 類(lèi)型,而 Capitalize 工具類(lèi)型要求處理的類(lèi)型需要是 string 類(lèi)型的子類(lèi)型,所以需要通過(guò)交叉運(yùn)算符進(jìn)行類(lèi)型過(guò)濾。

          此外,在對(duì)鍵進(jìn)行重新映射的過(guò)程中,我們可以通過(guò)返回?never?類(lèi)型對(duì)鍵進(jìn)行過(guò)濾:

          //?Remove?the?'kind'?property
          type?RemoveKindField?=?{
          ????[K?in?keyof?T?as?Exclude"kind">]:?T[K]
          };

          interface?Circle?{
          ????kind:?"circle";
          ????radius:?number;
          }

          type?KindlessCircle?=?RemoveKindField;
          //???type?KindlessCircle?=?{
          //???????radius:?number;
          //???};

          看完本文之后,相信你已經(jīng)了解映射類(lèi)型的作用了,也知道 TS 內(nèi)部一些工具類(lèi)型是如何實(shí)現(xiàn)的。你喜歡以這種形式學(xué) TS 么?喜歡的話,記得點(diǎn)贊與收藏喲。

          ?? 謝謝支持

          以上便是本次分享的全部?jī)?nèi)容,希望對(duì)你有所幫助^_^

          喜歡的話別忘了?分享、點(diǎn)贊、收藏?三連哦~。


          瀏覽 27
          點(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>
                  黑人大鷄巴XXX69式 | 亚洲黄色在线网站 | 日韩黄色在线视频 | 欧美一级爱爱 | 大香蕉网站在线 |