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

          共 5449字,需瀏覽 11分鐘

           ·

          2023-09-25 16:10

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

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

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

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

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

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

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

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

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

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

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

          // packages/runtime-core/src/apiCreateApp.ts
          export interface App<HostElement = any> {
            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ù)類型分別取了一個(gè)別名,從而方便在其他地方使用這些類型。

          接口

          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 = [numbernumber];

          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 這個(gè)庫,使用 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<CustomDataType, CustomReturnType>
            }
          }

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


          瀏覽 419
          點(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>
                  婷婷五月天激情在线观看 | 国产熟女一区二区 | 久久婷婷婬片A片AAA | 肏屄视频 | 天天干天天射天天日天天操 |