<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                &emsp;&emsp;在傳統的面向對象語言中,接口(Interface)好比協議,它會列出一系列的規則(即對行為進行抽象),再由類來實現這些規則。而TypeScript中的接口更加靈活,除了包含常規的作用之外,它還能擴展其它的類、為對象的類型命名以及約束值的結構等,大大消除了許多潛在的錯誤。 ## 一、屬性 &emsp;&emsp;TypeScript中的接口可通過聲明屬性和其類型來限制對象的結構。例如定義一個名為Person的接口,包含一個字符串類型的name屬性和一個數字類型的age屬性,如下所示。 ~~~js interface Person { name: string; age: number; } ~~~ &emsp;&emsp;當聲明一個Person類型的對象時,必須將兩個屬性都定義,并且類型也要與接口中的一致,如下所示。 ~~~js let worker: Person = { name: "strick", age: 28 }; ~~~ &emsp;&emsp;一旦在worker對象中少定義某個接口中的屬性或多一個在接口中未聲明的屬性,那么就會在編譯階段報錯。注意,TypeScript的類型檢查器不會比對屬性在接口和對象中的定義順序,只要名稱和類型匹配,就能編譯通過。 **1)可選屬性** &emsp;&emsp;TypeScript允許接口中的屬性定義為可選的,只要在屬性名后跟問號(?),就能變為可選屬性,如下所示。 ~~~js interface Person { school?: string; } ~~~ &emsp;&emsp;可選屬性既能預定義可能需要的屬性,也能在捕獲沒有的屬性時給出帶有啟發作用的錯誤提示,例如在創建worker對象時,定義一個schools屬性(如下所示),在編譯時就會報"'schools' does not exist in type 'Person'. Did you mean to write 'school'?"的錯誤。 ~~~js let worker: Person = { schools: "university" }; ~~~ &emsp;&emsp;由此可知,在對象中定義一個未在接口中聲明的屬性仍然是不允許的。 **2)只讀屬性** &emsp;&emsp;如果要讓對象的某個屬性只能在創建時被賦值,那么可以將readonly關鍵字作用于相應的接口屬性,使其變為只讀的,如下所示。 ~~~js interface Person { readonly gender: string; } ~~~ &emsp;&emsp;由于gender是一個只讀屬性,因此不能在對象初始化后對其進行修改,如下所示。 ~~~js let worker: Person = { //正確 gender: "男" }; worker.gender = "女"; //錯誤 ~~~ **3)任意屬性** &emsp;&emsp;當接口需要包含任意屬性時,可以通過索引的方式實現,如下所示,用方括號將索引名和索引類型包裹起來。 ~~~js interface Person { [prop: string]: string; } ~~~ &emsp;&emsp;在使用Person類型時,可以傳任意多個字符串類型的屬性,如下所示。 ~~~js let worker: Person = { name: "strick", gender: "男" }; ~~~ &emsp;&emsp;注意,一旦聲明了任意屬性之后,那么必選屬性和可選屬性都得是其類型的子類型。在下面的示例中,由于可選的age屬性的類型是number,不是string的子類型,因此在編譯時會報錯。 ~~~js interface Person { name: string; //正確 age?: number; //錯誤 [prop: string]: string; } ~~~ &emsp;&emsp;TypeScript除了支持字符串類型的索引之外,還支持數字類型的索引,如下所示。 ~~~js interface Person { [prop: number]: number; } ~~~ &emsp;&emsp;有一點需要注意,當在接口中同時定義字符串和數字兩種類型的索引時,后者對應的值類型得是前者的子類型。因為這個原因,導致下面的代碼無法在編譯時通過。 ~~~js interface Person { [prop: string]: string; [prop: number]: number; //錯誤 } ~~~ &emsp;&emsp;TypeScript之所以如此限制,是因為JavaScript會將數字自動轉換成字符串后再去索引對象,例如用10和“10”兩個值去索引,得到的結果是一樣的,所以兩種索引對應的值類型要保持一致。 ## 二、繼承 **1)類繼承接口** &emsp;&emsp;與C#、Java等面向對象語言一樣,TypeScript中的類也能繼承接口,并且接口中的成員會讓類強制實現。有了接口之后,它的任何更改都有可能導致編譯錯誤,從而就能保證相關代碼的同步。下面通過一個示例來演示類繼承接口,首先創建一個名為Person的接口,包含name屬性和getName()方法,如下所示。 ~~~js interface Person { name: string; getName(): string; } ~~~ &emsp;&emsp;然后再創建一個名為Member的類,通過implements關鍵字繼承Person接口,如下所示。在編譯時,一旦發現類中缺少接口的屬性或方法,就會馬上報錯。 ~~~js class Member implements Person { name: string = "strick"; getName() { return this.name; } } ~~~ &emsp;&emsp;類能繼承多個接口,只要在類中實現它的成員,就能編譯成功,如下所示,Member類繼承了Person和Profile兩個接口,限于篇幅原因,在其內部省略了name和getName()兩個成員的實現。 ~~~js interface Profile { school: string; } class Member implements Person, Profile { school: string = "university"; } ~~~ &emsp;&emsp;注意,類不能實現接口中的所有成員,例如在接口中定義一個構造器,再用一個類通過構造函數來實現這個接口,此時編譯將會失敗,代碼如下所示。 ~~~js interface Person { new (name: string); } class Member implements Person { constructor(name: string) { } } ~~~ &emsp;&emsp;類包含靜態和實例兩部分,由于編譯器只會對接口的實例部分進行類型檢查,而constructor()函數屬于類的靜態部分,因此會被忽略,從而導致無法在類中找到匹配的成員來實現接口。 &emsp;&emsp;如果要實現接口中的構造器,那么有兩種方式可供選擇。第一種是參數回調,如下代碼所示,Member類不再直接繼承Person接口,而是作為參數傳遞給createPerson()函數,并且其第一個參數被聲明為Person類型。 ~~~js class Member { constructor(name: string) { } } function createPerson(ctor: Person, name: string) { return new ctor(name); } createPerson(Member, "strick"); ~~~ &emsp;&emsp;第二種是類表達式,如下代碼所示,將Man變量聲明為Person類型,并把Member類賦給它。 ~~~js let Man: Person = class Member { constructor(name: string) { } } ~~~ **2)接口繼承接口** &emsp;&emsp;接口之間也可相互繼承,這樣既能更細粒度的分割接口,也能最大化的重用代碼。與類不同的是,只需將其它的接口成員復制過來,而不必實現它們。在下面的示例中,Square接口通過extends關鍵字繼承了Shape接口。 ~~~js interface Shape { background: string; } interface Square extends Shape { width: number; } ~~~ &emsp;&emsp;一個接口還可以繼承多個其它接口,創建出一個合成接口,如下所示,extends后面跟了Shape和Border兩個接口。 ~~~js interface Border { color: string; } interface Ellipse extends Shape, Border { angle: string; } ~~~ **3)接口繼承類** &emsp;&emsp;當接口繼承一個類時,它會繼承類的所有成員(包括私有和受保護的成員),但不會去實現它們。以下面的TextBox接口為例,它繼承了Control類。 ~~~js class Control { private width: number; protected height: number; } interface TextBox extends Control { type: string; } class Tel implements TextBox { type: string = "tel"; } ~~~ &emsp;&emsp;上例中的Tel類直接繼承了TextBox接口,雖然實現了接口中的type屬性,但仍然會報“Type 'Tel' is missing the following properties from type 'TextBox': width, height”的錯誤。因為Button接口繼承的width和height兩個屬性也需要實現。為了避免出現這些錯誤,可以通過Control的子類來實現TextBox接口,如下所示。 ~~~js class Password extends Control implements TextBox { type: string = "password"; } ~~~ ***** > 原文出處: [博客園-TypeScript躬行記](https://www.cnblogs.com/strick/category/1561745.html) [知乎專欄-TypeScript躬行記](https://zhuanlan.zhihu.com/pwts2019) 已建立一個微信前端交流群,如要進群,請先加微信號freedom20180706或掃描下面的二維碼,請求中需注明“看云加群”,在通過請求后就會把你拉進來。還搜集整理了一套[面試資料](https://github.com/pwstrick/daily),歡迎瀏覽。 ![](https://box.kancloud.cn/2e1f8ecf9512ecdd2fcaae8250e7d48a_430x430.jpg =200x200) 推薦一款前端監控腳本:[shin-monitor](https://github.com/pwstrick/shin-monitor),不僅能監控前端的錯誤、通信、打印等行為,還能計算各類性能參數,包括 FMP、LCP、FP 等。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看