<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 實(shí)現(xiàn)對(duì)不同類的通用擴(kuò)展

          共 1771字,需瀏覽 4分鐘

           ·

          2021-05-28 21:19

          有個(gè)奇怪的需求,對(duì)項(xiàng)目中存在的不同的類,給它們擴(kuò)展出一個(gè)相同的方法,以供消費(fèi)者調(diào)用。也就是說,要求從原來的類派生出來的新類,除了擁有原來類的方法外,還額外多出了一個(gè)新的通用方法。


          比如對(duì)于這樣兩個(gè)類,假如可以通過一個(gè)名字叫做 genericExtend() 的函數(shù)擴(kuò)展,那么其擴(kuò)展出的新類會(huì)多出一個(gè) genericMethod 方法:


          class A {

            a () {

              // ...

            }

          }

           

          class B {

            b () {

              // ...

            }

          }


          const instanceofA = new (genericExtend(A))()

          const instanceofB = new (genericExtend(B))()


          instanceofA.a() // ok

          instanceofA.genericMethod() // ok


          instanceofB.b() // ok

          instanceofB.genericMethod() // ok


          這個(gè)需求看起來很奇怪,但也不是完全不合理,比如原始的 A 和 B,甚至 C 以及 D 等等類,是第三方來的依賴,雖然不完全一樣,但是又有一些類似的地方,可以被通用處理。同時(shí)項(xiàng)目中又大量存在直接調(diào)用它們的原始方法的地方,不能全部替換,因此,可以將這些實(shí)例替換為被擴(kuò)展后的實(shí)例,由于被擴(kuò)展后的實(shí)例是原始類的子類,所以原有調(diào)用不用改變。而對(duì)于新的希望應(yīng)用通用處理邏輯的地方,可以直接調(diào)用新的方法 genericMethod()。


          一個(gè)幼稚的實(shí)現(xiàn)


          具體實(shí)現(xiàn)如下:


          type Constructor = new (...args: any[]) => any


          function genericExtend<T extends Constructor>(target: T) {

            return class GenericExtended extends target {

              constructor(...args: any[]) {

                super(...args)

              }


              genericMethod() {

                ...

              }

            }

          }


          這個(gè)實(shí)現(xiàn)完全能滿足最初提出的需求,并且,可以通過聯(lián)合類型,實(shí)現(xiàn)靜態(tài)類型檢查,比如對(duì) instanceofA 定義一個(gè)聯(lián)合類型,那么無論調(diào)用原始方法還是新的通用方法,都能享受到靜態(tài)類型的約束:


          const instanceofA: GenericExtended & A = new (genericExtend(A))()

          const instanceofB = new (genericExtend(B))()


          instanceofA.a() // ok,有代碼智能提示

          instanceofA.genericMethod() // ok,有代碼智能提示


          instanceofB.b() // ok,不報(bào)錯(cuò),但是沒有靜態(tài)類型檢查

          instanceofB.genericMethod() // ok,不報(bào)錯(cuò),但是沒有靜態(tài)類型檢查


          幼稚實(shí)現(xiàn)不好的地方


          雖然幼稚的實(shí)現(xiàn)完全能夠工作,并且我將它用在了實(shí)際的工程里,但是它有這些缺點(diǎn):


          • 在實(shí)現(xiàn)上使用了 any 關(guān)鍵字
          • 在聲明實(shí)例的類型時(shí),需要使用聯(lián)合類型的方式,比較丑
          • 不顯式聲明類型,就沒有類型檢查,沒有觸發(fā) TypeScript 的類型自動(dòng)推斷

          不知道這個(gè)需求會(huì)不會(huì)是某種通用模式?從而有現(xiàn)成的更加優(yōu)雅的實(shí)現(xiàn)方案?可能受制于自己的認(rèn)知,網(wǎng)上搜索了很久,沒有找到優(yōu)雅的通用的實(shí)現(xiàn)。希望有高人能指點(diǎn)指點(diǎn)。


          瀏覽 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>
                  狠狠操狠狠操狠狠操 | 91黄色一级电影 | 国产操逼AV电影 | 亚洲国产精品视频 | 日韩一级片在线 |