<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 功能強大 支持多語言、二開方便! 廣告
                >[success] # 什么是泛型 部分內容摘自:[TS入門教程 ](https://ts.xcatliu.com/advanced/generics.html) ~~~ 1.泛型(Generics)是指在定義函數、接口或類的時候,不預先指定具體的 類型,而在使用的時候再指定類型的一種特性。 2.就是一種不確定的數據類型,可以把運行時的問題提前到編譯時期(java 里是這么說的 我覺得在ts 應該同理的) 3.簡單粗暴的說不想丟失'ts' 的類型檢查 ~~~ >[info] ## 舉個例子 ~~~ 1.現在有個方法,這個方法有兩個參數,一個參數是用來占位數組的項的占位 參數'value',一個是當前數組長度的'items' ~~~ >[danger] ##### js 中的寫法 ~~~ 1.下面我們又做了一個操作: 我們想將當前傳入參數的長度重新返回一個數 組,但是這時候疏忽傳入了數字,其實按照js邏輯思想我們會對類型做判斷 然后強大我的代碼,本質上這種 錯誤對'前端人員'來說避免是正常操作 ~~~ ~~~ function getArray(value,items){ return new Array(items).fill(value) } getArray(1,1).map((items)=>{ return items.length }) ~~~ * 打印結果 ~~~ [undefined] ~~~ >[danger] ##### Ts -- 中如何來寫(any) ~~~ 1.直接將上面代碼轉譯成ts 寫法如下 2.下面的寫法是直接按照'ts' 思路簡單轉譯,因為不確定'value' 是什么類型以 及不確定,返回類型這里用了'any' 3.這么做之后和'js'沒區別 ~~~ ~~~ function getArray(value:any,items:number = 5):any[]{ return new Array(items).fill(value) } getArray(1,1).map((items)=>{ return items.length }) ~~~ * 打印結果 ~~~ [undefined] ~~~ >[danger] ##### Ts -- 中如何來寫(聯合類型) ~~~ 1.然后想到了聯合類型寫法,返回值是聯合類型不就解決了么,你返回的可 能是'string' 也可能是'number' 不就好了么 2.實踐后發現,在編寫的過程這個聯合類型只承認雙方共有屬性舉個下面的 案例說明 ~~~ ~~~ function getArray(value:any,items:number = 5):(string|number)[]{ return new Array(items).fill(value) } getArray("1",1).map((items)=>{ return items.length }) ~~~ * 編寫過程幫我們校驗了,但是length 不是兩個類型共有的 ![](https://box.kancloud.cn/9a600de2ebd3f8252d4a3f0a489f14e9_587x181.png) * 能改么 答案是能,但是改了還不如第一種 ~~~ // 自信的程序員 我就斷言你傳入的是 字符 getArray("1",1).map((items)=>{ return (items as string).length }) ~~~ >[danger] ##### Ts -- 中如何來寫(函數重載) ~~~ 1.按照現階段的知識儲備只能用這個了函數的重載 ~~~ ~~~ function getArray(value:string,items:number):string[] function getArray(value:number,items:number):number[] function getArray(value:any,items:number = 5):(string|number)[]{ return new Array(items).fill(value) } getArray("1",1).map((items)=>{ return items.length }) ~~~ * 上面的案例傳的是字符串那么我們串數字呢 ~~~ 1.傳數字的話整個代碼在我們編寫的時候就給提示了真的好棒(我的內心是無 力吐槽) ~~~ ![](https://box.kancloud.cn/99a275b94f3c6a14d1c57a37aa3366e4_669x265.png) >[info] ## 正式使用泛型 ~~~ 1.上面的案例我們雖然找到了解決方法,但有沒有更好的方法來解決呢,別 忘了開篇說的 '泛型是一種不確定的數據類型,可以把運行時的問題提前到編譯時期' ~~~ >[danger] #### 泛型的寫法 ~~~ 1.我們在函數名后添加了 <T>,其中 T 用來指代任意輸入的類型,在后面 的輸入 value: T 和輸出 Array<T> 中即可使用了。 2.'下面案例也可以不用T表示','A,B,C...' 隨意 ~~~ * 用泛型 --- 也能實心函數重載的效果 ~~~ function getArray<T>(value:T,items:number = 5):T[]{ return new Array(items).fill(value) } // 縮寫 可以將明確的類型省略,編譯器會給傳參來判斷 getArray("1",1).map((items)=>{ return items.length }) // 不縮寫 // getArray<string>("1",1).map((items)=>{ // return items.length // }) ~~~ >[danger] ##### 泛型傳入多個不同類型參數 ~~~ 1.泛型傳入多個不同類型參數 ~~~ ~~~ function getArray<T,U>(value1:T,value2:U,items:number = 5):Array<[T,U]>{ return new Array(items).fill([value1,value2]) } getArray("1",1,1).forEach((items)=>{ console.log(items[0].length) console.log(items[1].length) // 幫我們自動檢測數字沒有length 屬性 }) ~~~ >[danger] ##### 函數表達式/函數別名/接口 --配合泛型寫法 * 函數表達式的定義方式 ~~~ let getArray: <T>(arg: T, times: number) => T[] getArray = (arg: any, times: number) => { return new Array(times).fill(arg) } getArray(123, 3).map((item) => item.length) // 報錯幫你自動檢測了 ~~~ * 函數別名 ~~~js type GetArray = <T>(arg: T, times: number) => T[] let getArray: GetArray = (arg: any, times: number) => { return new Array(times).fill(arg) } ~~~ * 接口類型 ~~~ interface GetArray<T> { (arg: T, times: number): T[], array: T[] } //泛型和 interface interface KeyPair<T, U> { key: T; value: U; } let kp1: KeyPair<number, string> = { key: 1, value: "str"} let kp2: KeyPair<string, number> = { key: "str", value: 123} ~~~ >[danger] ##### 泛型約束 -- 來約束泛型參數 ~~~ 1.現在泛型會根據你傳入的值還進行動態類型,問題來了有一些不具備我們代碼中屬性的值傳入,會導致編譯 階段報錯如圖一,這時候需要對泛型傳入的參數加以約束,這時候使用泛型約束 2.思路就是讓泛型類型去繼承接口或者一些類,讓在編譯過程去檢測傳入的,泛型約束需要關鍵字('extends') 泛型是具有當前指定的屬性 3.簡單的說泛型約束解決在函數內部使用泛型變量的時候,由于事先不知道它是哪種類型,所以不能隨意的操 作它的屬性或方法 4.有些更詳細的案例可以看一下開篇文章的地址 ~~~ * 圖一 ![](https://img.kancloud.cn/bf/34/bf34f39b7fc6c6f4873bbeefa7ab06af_500x78.png) ~~~ interface ValueWithLength { length: number } const getArray = <T extends ValueWithLength>(arg: T, times): T[] => { return new Array(times).fill(arg) } getArray([1, 2], 3) getArray('123', 3) getArray({ length: 2, }, 3) getArray(1, 3) // 報錯 數字類型沒有length ~~~ >[danger] ##### 泛型約束結合索引類型的使用 ~~~ 1. 下面的案例 實現的是,泛型參數必須是傳入對象key中存在的,這是一個 繼承了 keyof 一個屬性 ~~~ ~~~ const getProps = <T, K extends keyof T>(object: T, propName: K) => { return object[propName] } const objs = { a: 'a', b: 'b', } getProps(objs, 'a') ~~~ >[danger] ##### 防止思維定式 ~~~ function getExcludeProp<T extends {props:string}>(obj:T){ return obj } // getExcludeProp({name:'w'}) // 報錯 getExcludeProp({name:'w',props:'w'}) ~~~ >[danger] ##### 泛型和類 ~~~ class Queue { private data = []; push(item) { return this.data.push(item) } pop() { return this.data.shift() } } const queue = new Queue() queue.push(1) queue.push('str') console.log(queue.pop().toFixed()) console.log(queue.pop().toFixed()) // 在上述代碼中存在一個問題,它允許你向隊列中添加任何類型的數據,當然,當數據被彈出 // 隊列時,也可以是任意類型。在上面的示例中,看起來人們可以向隊列中添加string 類型的數據 // 但是那么在使用的過程中,就會出現我們無法捕捉到的錯誤, class Queue<T> { private data = []; push(item: T) { return this.data.push(item) } pop(): T { return this.data.shift() } } const queue = new Queue<number>() ~~~
                  <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>

                              哎呀哎呀视频在线观看