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

          TypeScript-泛型-2-泛型約束

          共 4520字,需瀏覽 10分鐘

           ·

          2021-08-12 18:28

          ?

          鬼哥本周將通過(guò)幾篇優(yōu)秀的Typescript文章,讓大家學(xué)習(xí)到Typescript一些高級(jí)的用法,讓大家對(duì)Typescript更加的深入理解,并且更好實(shí)踐到工作當(dāng)中,【一共五篇文章】,關(guān)注我們一起完成這個(gè)系列的學(xué)習(xí)

          原文:https://github.com/leslie1943

          ?


          ?? 泛型約束?

          ?

          有時(shí)我們可能希望限制每個(gè)類型變量接收的類型數(shù)量,這就是泛型約束的作用.

          ?
          ?? 4.1 確保屬性存在
          • 希望類型變量對(duì)應(yīng)的類型上存在某些屬性. 這時(shí), 除非我們顯式地將特定屬性定義為類型變量, 否則編譯器不會(huì)知道他們的存在.
          • 一個(gè)很好的例子是在處理字符串或數(shù)組時(shí), 我們會(huì)假設(shè) length 屬性是可用的. 讓我們?cè)俅问褂?identity 函數(shù)并嘗試輸出參數(shù)的長(zhǎng)度.
          function identity<T>(arg: T): T {
            console.info(arg.length)
            return arg
          }
          • 在這種情況下, 編譯器將不會(huì)知道 T 確實(shí)含有 length 屬性, 尤其是在可以將任何類型賦給類型變量 T 的情況下.我們需要做的就是讓類型變量 extends 一個(gè)含有我們所需屬性的接口, 比如這樣
          interface Length {
            length: number
          }
          function identity<T extends Length>(arg: T): T {
            console.info(arg.length)
            return arg
          }
          • T extends Length 用于告訴編譯器, 我們支持已經(jīng)實(shí)現(xiàn) Length 接口的任何類型. 之后, 當(dāng)我們使用不含有 length 屬性的對(duì)象作為參數(shù)調(diào)用 identity 函數(shù)時(shí), TypeScript 會(huì)提示相關(guān)的錯(cuò)誤信息:
          // identity(52) 
          // Argument of type 'number' is not assignable to parameter of type 'Length'.ts(2345)
          • 此外, 我們還可以使用 , 號(hào)來(lái)分隔多種約束類型, 比如:<T extends Length, Type2, Type3>. 而對(duì)于上述的 length 屬性問(wèn)題來(lái)說(shuō), 如果我們顯式地將變量設(shè)置為數(shù)組類型, 也可以解決該問(wèn)題, 具體方式如下
          function identity2<T>(arg: T[]): T[] {
            console.info(arg.length)
            return arg
          }
          identity2([123]) // function identity2<number>(arg: number[]): number[]
          identity2([`1``2``3`]) // function identity2<string>(arg: string[]): string[]

          // 或者

          function identity3<T>(arg: Array<T>): Array<T{
            console.info(arg.length)
            return arg

          ?? 4.2 檢查對(duì)象上的鍵是否存在

          • 泛型約束的另一個(gè)常見(jiàn)的使用場(chǎng)景就是檢查對(duì)象上的鍵是否存在. 不過(guò)在看具體示例之前, 我們得來(lái)了解一下 keyof 操作符, keyof 操作符是在 TypeScript 2.1 版本引入的, 該操作符可以用于獲取某種類型的所有鍵, 其返回類型是聯(lián)合類型. 舉個(gè) keyof 的使用示例:
          interface Person {
            name: string
            age: number
            location: string
          }

          type K1 = keyof Person // 'name' | 'age' | 'location'
          type K2 = keyof Person[] // number | "length" | "push" | "concat" | ...
          type K3 = keyof { [x: string]: Person } // string | number
          • 通過(guò)keyof操作符, 我們就可以獲取指定類型的所有鍵, 之后我們就可以結(jié)合前面介紹的extends約束,限制輸入屬性名包含在keyof返回的聯(lián)合類型中.
          interface Person {
            name: string
            age: number
            location: string
          }

          function getProperty<TK extends keyof T>(obj: T, key: K): T[K{
            return obj[key]
          }

          const person: Person = {
            name: 'su',
            age: 22,
            location: 'dalian',
          }

          // function getProperty<Person, "age">(obj: Person, key: "age"): number
          console.info('getProperty(person, "age")', getProperty(person, 'age')) 

          // function getProperty<Person, "name">(obj: Person, key: "name"): string
          console.info('getProperty(person, "name")', getProperty(person, 'name'))
          • 在以上的 getProperty 函數(shù)中, 我們通過(guò) K extends keyof T 確保參數(shù) key 一定是對(duì)象中含有的鍵, 這樣就不會(huì)發(fā)生運(yùn)行時(shí)錯(cuò)誤. 這是一個(gè)類型安全的解決方案, 與簡(jiǎn)單調(diào)用 let value = obj[key] 不同.
          demo
          enum Difficulty {
            Easy,
            Medium,
            Hard,
          }

          function getProperty<TK extends keyof T>(obj: T, key: K): T[K{
            return obj[key]
          }

          let tsInfo = {
            name: 'TypeScript',
            supersetOf: 'JavaScript',
            difficulty: Difficulty.Medium,
          }

          let difficulty: Difficulty = getProperty(tsInfo, 'difficulty'// OK
          let name: string = getProperty(tsInfo, 'name'// OK
          // let supersetof: string = getProperty(tsInfo, 'superset_of') 
          // ? Argument of type '"superset_of"' is not assignable to parameter of type '"difficulty" | "name" | "supersetOf"'.ts(2345)
          • 很明顯通過(guò)使用泛型約束, 在編譯階段我們就可以提前發(fā)現(xiàn)錯(cuò)誤, 大大提高了程序的健壯性和穩(wěn)定性.

          關(guān)注公眾號(hào)添加鬼哥微信,和鬼哥一起學(xué)習(xí)

          ?? 看完三件事

          如果你覺(jué)得這篇內(nèi)容對(duì)你挺有啟發(fā),不妨:

          • 點(diǎn)個(gè)【在看】,或者分享轉(zhuǎn)發(fā),讓更多的人也能看到這篇內(nèi)容

          • 點(diǎn)擊↓面關(guān)注我們,一起學(xué)前端

          • 長(zhǎng)按↓面二維碼,添加鬼哥微信,一起學(xué)前端



          瀏覽 32
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(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>
                  欧美中文字幕免费在线观看 | 青娱乐精品在线视频 | 麻豆18禁| 日本级婬乱片A片AAA毛片地址 | 亚洲1区无码 |