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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                &emsp;&emsp;TypeScript是一種基于結構類型的語言,可根據其成員來描述類型。以結構相同的Person接口和Programmer類為例,如下所示。 ~~~ interface Person { name: string; } class Programmer { name: string; } let person: Person = new Programmer(); ~~~ &emsp;&emsp;由于結構類型的關系,因此當變量聲明為Person類型時,可通過Programmer類實例化。由此可知,結構類型只關注類型的組成結構,而名稱并不重要。 ## 一、函數 &emsp;&emsp;在判斷兩個函數的兼容性時,需要考慮參數數量、返回值類型等多個方面。 **1)參數數量** &emsp;&emsp;假設有兩個函數add()和sum(),它們的參數數量不同,后者比前者多一個參數,而函數的返回值類型相同,如下所示。 ~~~ let add = (x: number) => 0; let sum = (y: number, z: number) => 0; ~~~ &emsp;&emsp;當把add賦給sum時,編譯能成功執行;而反之,則會報錯,如下所示。 ~~~ sum = add; //正確 add = sum; //錯誤 ~~~ &emsp;&emsp;由此可知,參數少的函數不能賦給參數多的;而反過來時,需要確保每個位置所對應的參數類型保持一致,不過參數名稱可以不同。 **2)返回值類型** &emsp;&emsp;假設有兩個函數add()和sum(),它們沒有參數,后者的返回值比前者多一個屬性,如下所示。 ~~~ let add = () => ({ x: 1 }); let sum = () => ({ x: 1, y: 2}); ~~~ &emsp;&emsp;當把sum賦給add時,編譯能成功執行;而反之,則會報錯,如下所示。 ~~~ add = sum; //正確 sum = add; //錯誤 ~~~ &emsp;&emsp;由此可知,源函數的返回值類型得是目標函數返回值的子類型。 **3)參數類型** &emsp;&emsp;TypeScript中的參數類型需要同時滿足協變和逆變,即雙向協變。協變比較好理解,是指子類型兼容父類型,而逆變正好與協變相反。在下面的示例中,定義了父類Person和子類Programmer,Programmer類覆蓋了Person類中的work()方法,并且其參數類型聲明的更加寬泛。 ~~~ class Person { work(msg: string | undefined) { } } class Programmer extends Person { work(msg: string) { } } ~~~ &emsp;&emsp;接下來聲明兩個函數,它們的參數類型分別是Person和Programmer兩個類,如下所示,其中person()函數是programmer()函數的子類型。 ~~~ let person = (x: Person) => 0; let programmer = (x: Programmer) => 0; ~~~ &emsp;&emsp;由于參數類型是雙向協變的,因此兩個變量之間可相互賦值,如下所示。 ~~~ person = programmer; programmer = person; ~~~ **4)可選參數和剩余參數** &emsp;&emsp;在比較函數的兼容性時,不需要匹配可選參數。以下面的pls()和add()兩個函數為例,pls()中的兩個參數必傳,而add()中的第二個參數是可選的。 ~~~ let pls = (x: number, y: number) => 0; let add = (x: number, y?: number) => 0; pls = add; add = pls; ~~~ &emsp;&emsp;雖然參數不同,但是兩個函數仍然是兼容的,并且可以相互賦值。剩余參數相當于無限個可選參數,也不會被匹配。下面示例中的sum()函數只聲明了剩余參數,它與pls()和add()兩個函數都是兼容的。 ~~~ let sum = (...args: number[]) => 0; pls = sum; sum = pls; add = sum; sum = add; ~~~ **5)函數重載** &emsp;&emsp;當比較存在多個重載的函數時,其每個重載都要在目標函數上找到對應的函數簽名,以此確保目標函數能在源函數所有可調用的地方調用,如下所示。 ~~~ interface add { (x: number, y: string): any; (x: number, y: number): number; } function sum(x: number, y: string): any; function sum(x: number, y: number): number; let func: add = sum; ~~~ ## 二、枚舉 &emsp;&emsp;來自于不同枚舉類型的枚舉值,被認為是不兼容的,如下所示,當把Direction.Up賦給color變量時,在編譯階段會報錯。 ~~~ enum Color { Red, Green, Blue } enum Direction { Up, Down, Left, Right } let color = Color.Red; //正確 color = Direction.Up; //錯誤 ~~~ &emsp;&emsp;數字枚舉和數字類型相互兼容,如下所示,color變量被賦予了枚舉成員,digit變量是一個數字,它們之間可以相互賦值。 ~~~ let color = Color.Red; let digit = 1; color = digit; digit = color; ~~~ &emsp;&emsp;字符串枚舉無法兼容字符串類型,如下所示,當把field變量賦給Color的枚舉成員時,在編譯階段會報錯,但反過來可以正確執行。 ~~~ enum Color { Red = "RED", Green = "GREEN", Blue = "BLUE" } let color = Color.Red; let field = "PURPLE"; color = field; //錯誤 field = color; //正確 ~~~ ## 三、類 &emsp;&emsp;類與對象字面量和接口類似,但類包含靜態和實例兩部分。在比較兩個類實例時,僅匹配它們的實例成員,而靜態成員和構造函數不影響兼容性,因為它們在比較時會被忽略。 &emsp;&emsp;在下面的示例中,創建了Person和Programmer兩個類,雖然Programmer類包含了一個靜態屬性,并且其構造函數與Person類不同,但是它們之間可以相互兼容。 ~~~ class Person { name: string; constructor(name: string) { } } class Programmer { name: string; static age: number; constructor(name: string, age: number) { } } let person: Person; let programmer: Programmer; person = programmer; programmer = person; ~~~ &emsp;&emsp;類的私有成員和受保護成員會影響兼容性,TypeScript要求它們必須來源于同一個類,從而既能保證父類兼容子類,也能避免與其它相同結構的類兼容。 &emsp;&emsp;在下面的示例中,Person和Teacher兩個類都包含一個同名的私有屬性,Programmer是Person的子類,三個變量的類型對應這三個類。 ~~~ class Person { private name: string; } class Teacher { private name: string; } class Programmer extends Person { } let person: Person; let programmer: Programmer; let teacher: Teacher; ~~~ &emsp;&emsp;person和programmer兩個變量可相互賦值,因為它們的私有成員來源于同一個類,如下所示。 ~~~ person = programmer; programmer = person; ~~~ &emsp;&emsp;雖然person和teacher兩個變量的結構相同,但是它們的私有成員來源于兩個不同的類,因此無法相互賦值,如下所示。 ~~~ person = teacher; //錯誤 teacher = person; //錯誤 ~~~ ## 四、泛型 &emsp;&emsp;當泛型接口中的類型參數未使用時,不會影響其兼容性,如下所示,x和y兩個變量可相互賦值。 ~~~ interface Person<T> { } let x: Person<number>; let y: Person<string>; x = y; y = x; ~~~ &emsp;&emsp;當泛型接口中的類型參數被一個成員使用時,就會影響其兼容性,如下所示,x和y兩個變量不可相互賦值。 ~~~ interface Person<T> { data: T; } let x: Person<number>; let y: Person<string>; x = y; //錯誤 y = x; //錯誤 ~~~ &emsp;&emsp;當比較未指定參數類型的泛型函數時,在檢查兼容性之前會將其替換成any類型,例如下面的兩個函數,相當于對“(x: any)=>any”和“(y: any)=>any”進行匹配,因此可相互賦值。 ~~~ let send = function<T>(x: T): T { return x; } let func = function<U>(y: U): U { return y; } send = func; func = send; ~~~ &emsp;&emsp;泛型類的兼容性規則與之前所述一致。 ***** > 原文出處: [博客園-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>

                              哎呀哎呀视频在线观看