<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】1322- type 和 interface 傻傻分不清楚?

          共 3281字,需瀏覽 7分鐘

           ·

          2022-05-20 12:00

          阿寶哥精心準(zhǔn)備的《輕松學(xué) TypeScript》?視頻教程已經(jīng)更新到第十二期了,通過形象生動的動畫,讓你輕松搞懂 TypeScript 的難點(diǎn)和核心知識點(diǎn)!

          如果你簡歷上的技能有寫 TypeScript,那么面試官可能會問你 type 和 interface 之間有什么區(qū)別?你知道怎么回答這個問題么?如果不知道的話,那看完本文也許你就懂了。

          類型別名 type 可以用來給一個類型起個新名字,當(dāng)命名基本類型或聯(lián)合類型等非對象類型時(shí)非常有用:

          type?MyNumber?=?number;
          type?StringOrNumber?=?string?|?number;
          type?Text?=?string?|?string[];
          type?Point?=?[number,?number];
          type?Callback?=?(data:?string)?=>?void;

          在 TypeScript 1.6 版本,類型別名開始支持泛型。我們工作中常用的 Partial、Required、Pick、Record 和 Exclude 等工具類型都是以 type 方式來定義的。

          //?lib.es5.d.ts
          type?Partial?=?{
          ????[P?in?keyof?T]?:?T[P];
          };

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

          type?Pickextends?keyof?T>?=?{
          ????[P?in?K]:?T[P];
          };

          type?Recordextends?keyof?any,?T>?=?{
          ????[P?in?K]:?T;
          };

          type?Exclude?=?T?extends?U???never?:?T;

          而接口 interface 只能用于定義對象類型,Vue 3 中的 App 對象就是使用 interface 來定義的:

          //?packages/runtime-core/src/apiCreateApp.ts
          export?interface?App?{
          ??version:?string
          ??config:?AppConfig
          ??use(plugin:?Plugin,?...options:?any[]):?this
          ??mixin(mixin:?ComponentOptions):?this
          ??component(name:?string):?Component?|?undefined?//?Getter
          ??component(name:?string,?component:?Component):?this?//?Setter
          ??directive(name:?string):?Directive?|?undefined
          ??directive(name:?string,?directive:?Directive):?this
          }

          由以上代碼可知,在定義接口時(shí),我們可以同時(shí)聲明對象類型上的屬性和方法。了解 type 和 interface 的作用之后,我們先來介紹一下它們的相似之處。

          1、類型別名和接口都可以用來描述對象或函數(shù)

          類型別名

          type?Point?=?{
          ??x:?number;
          ??y:?number;
          };

          type?SetPoint?=?(x:?number,?y:?number)?=>?void;

          在以上代碼中,我們通過 type 關(guān)鍵字為對象字面量類型和函數(shù)類型分別取了一個別名,從而方便在其他地方使用這些類型。

          接口

          interface?Point?{
          ??x:?number;
          ??y:?number;
          }

          interface?SetPoint?{
          ??(x:?number,?y:?number):?void;
          }

          2、類型別名和接口都支持?jǐn)U展

          類型別名通過 &(交叉運(yùn)算符)來擴(kuò)展,而接口通過 extends 的方式來擴(kuò)展。

          類型別名擴(kuò)展

          type?Animal?=?{
          ??name:?string
          }

          type?Bear?=?Animal?&?{?
          ??honey:?boolean?
          }

          const?bear:?Bear?=?getBear()?
          bear.name
          bear.honey

          接口擴(kuò)展

          interface?Animal?{
          ??name:?string
          }

          interface?Bear?extends?Animal?{
          ??honey:?boolean
          }

          此外,接口也可以通過 extends 來擴(kuò)展類型別名定義的類型:

          type?Animal?=?{
          ??name:?string
          }

          interface?Bear?extends?Animal?{
          ??honey:?boolean
          }

          同樣,類型別名也可以通過 &(交叉運(yùn)算符)來擴(kuò)展已定義的接口類型:

          interface?Animal?{
          ??name:?string
          }

          type?Bear?=?Animal?&?{?
          ??honey:?boolean?
          }

          了解完 type 和 interface 的相似之處之后,接下來我們來介紹它們之間的區(qū)別。

          1、類型別名可以為基本類型、聯(lián)合類型或元組類型定義別名,而接口不行

          type?MyNumber?=?number;
          type?StringOrNumber?=?string?|?number;
          type?Point?=?[number,?number];

          2、同名接口會自動合并,而類型別名不會

          同名接口合并

          interface?User?{
          ??name:?string;
          }

          interface?User?{
          ??id:?number;
          }

          let?user:?User?=?{?id:?666,?name:?"阿寶哥"?};
          user.id;?//?666
          user.name;?//?"阿寶哥"

          同名類型別名會沖突

          type?User?=?{
          ??name:?string;
          };

          //?標(biāo)識符“User”重復(fù)。ts(2300)
          type?User?=?{ //Error
          ??id:?number;
          };

          利用同名接口自動合并的特性,在開發(fā)第三方庫的時(shí)候,我們就可以為使用者提供更好的安全保障。比如 webext-bridge 這個庫,使用 interface 定義了 ProtocolMap 接口,從而讓使用者可自由地?cái)U(kuò)展 ProtocolMap 接口。

          之后,在利用該庫內(nèi)部提供的 onMessage 函數(shù)監(jiān)聽自定義消息時(shí),我們就可以推斷出不同消息對應(yīng)的消息體類型。

          擴(kuò)展 ProtocolMap 接口

          import?{?ProtocolWithReturn?}?from?'webext-bridge'

          declare?module?'webext-bridge'?{
          ??export?interface?ProtocolMap?{
          ????foo:?{?title:?string?}
          ????bar:?ProtocolWithReturn
          ??}
          }

          監(jiān)聽自定義消息

          import?{?onMessage?}?from?'webext-bridge'

          onMessage('foo',?({?data?})?=>?{
          ??//?type?of?`data`?will?be?`{?title:?string?}`
          ??console.log(data.title)
          }

          如果你感興趣的話,可以看一下該項(xiàng)目的源碼。若遇到問題,可以跟阿寶哥交流。最后我們來總結(jié)一下類型別名和接口的一些使用場景。

          使用類型別名的場景:

          • 定義基本類型的別名時(shí),使用 type
          • 定義元組類型時(shí),使用 type
          • 定義函數(shù)類型時(shí),使用 type
          • 定義聯(lián)合類型時(shí),使用 type
          • 定義映射類型時(shí),使用 type

          使用接口的場景:

          • 需要利用接口自動合并特性的時(shí)候,使用 interface
          • 定義對象類型且無需使用 type 的時(shí)候,使用 interface

          掃碼查看?輕松學(xué) TypeScript?系列視頻教程

          (目前已更新?12?期)

          閱讀完本文,相信你已經(jīng)了解 type 和 interface 之間的區(qū)別了。你喜歡以這種形式學(xué) TS 么?喜歡的話,記得點(diǎn)贊與收藏喲。

          瀏覽 20
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(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>
                  日本三级无码 | 亚洲AV成人无码精品区 | 免费无码一区二区三区四区五区 | 欧美精品蜜桃69桔色 | 超碰操朝鲜女人网 |