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

          TS 中實現(xiàn) IsEqual 工具

          共 3605字,需瀏覽 8分鐘

           ·

          2021-09-05 00:51

          最近刷體操題,很多場景都需要判斷兩個類型是否相同,那么如何優(yōu)雅地實現(xiàn)isEuqal<A, B>這樣一個工具類 呢?

          很自然地想到了使用 extends,兩個類型互相 extends 的話那不就表示類型相同了么?

          于是就有了第一種實現(xiàn)

          原始方法

          type IsEqual<A, B> = A extends B ? B extends A ? true : false : false

          看起來是不是很容易?讓我們找?guī)讉€??測試一下

          type IsEqual<A, B> = A extends B ? B extends A ? true : false : false

          type A1 = IsEqual<string, string> // true
          type A2 = IsEqual<string, number> // false
          type A3 = IsEqual<{ name: string }, { name: string }> // true
          type A4 = IsEqual<{ name: string}, { age: number }> // false
          type A5 = IsEqual<{ name: string}, { name?: string }> // false

          看起來效果也很好,那是不是這個實現(xiàn)就是完美了呢?

          讓我們再看看其他的??

          type A6 = IsEqual<true, boolean> // boolean
          type A7 = IsEqual<1 | 2, 1> // boolean

          對于這兩個??,我們期望得到的結果都是 false,但是實際結果卻都是 boolean,這就有點奇怪了,明明返回的結果應該是 true or false,怎么返回了一個 boolean

          事實上,boolean 類型在 ts 中和 true | false 是等價的,所以返回的類型是 boolean 其實就是返回了 true | false,也就是在 IsEqual 這個工具類里面兩個分支都走了。而為什么會走兩個分支呢?這又是因為泛型和 extends 兩者結合產(chǎn)生的 distributive conditional types這樣一種效應導致的。

          既然第一種實現(xiàn)不太完美,那我們就該對癥下藥去解決第一個缺陷的地方,因為 extends 和泛型是這個實現(xiàn)里面必備的要素,但是又想避免由于這兩者結合所帶來的的 distributive conditional types 造成的影響。如何解決這種影響呢?也就是如何去消除 distributive conditional types 呢?ts官方告訴我們,給泛型套上一個[]就可以消除這種效應

          于是,我們有了第二種實現(xiàn)

          削微改進

          type IsEqual<A, B> = [A] extends [B] ? [B] extends [A] ? true : false : false

          當然,如果你嫌這樣的實現(xiàn)太丑陋的話可以簡化一下

          type IsEqual<A, B> = [A, B] extends [B, A] ? true : false

          這兩種實現(xiàn)是等價的

          讓我們再去試試剛剛沒有通過的兩個??

          type A7 = IsEqual<true, boolean> // false
          type A8 = IsEqual<1 | 2, 1> // false

          我們會發(fā)現(xiàn)這一回這倆??都可以完美通過了,是不是大功告成了呢?

          (其實這個實現(xiàn)已經(jīng)可以幫助我們解決很大一部分的問題了)

          但是很遺憾,還有些頑固??拒絕通過

          type A9 = IsEqual<any, string> // true
          type A10 = IsEqual< { name: string }, { readonly name: string }> // true

          unbelivable, 為什么 anystring 是相同的類型,為什么 readonly 不能被區(qū)分出來?

          • tsany 可以賦給任何類型,任何類型也都可以賦給 any,這就意味著 any 和任意類型之間都是 assignable 的,對于 extends 而言就是都可以互相 extends,這也就是為什么 A9 類型是 true
          • readonly 不會改變 assignable

          對于以上這兩種頑固情況該怎么解決呢

          經(jīng)過一通 Google,終于找到了一個相對完美的實現(xiàn)

          Final version

          type IsEqual<A, B> = (<T>() => T extends A ? 1 : 2) extends (<T1>() => T1 extends B ? 1 : 2) ? true : false

          具體可參考 github.com/microsoft/T…[1]

          再來看一下剛剛的頑固??

          type A9 = IsEqual<any, string> // false
          type A10 = IsEqual< { name: string }, { readonly name: string }> // false

          最終版可以幫助你解決 Get Readonly Keys[2]

          結語:

          其實最終版的實現(xiàn)我還不是很懂,只知道是使用了 ts 內部的 isTypeIdenticalTo 實現(xiàn)的,如果有知道的大佬,請不吝賜教

          原文地址

          https://juejin.cn/post/7001857261756743694

          ?? 看完三件事

          非常棒的一篇Ts實用文章,

          如果你覺得這篇內容對你挺有啟發(fā),不妨:

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

          • 點擊↓面關注我們,一起學前端

          • 長按↓面二維碼,添加鬼哥微信,一起學前端



          瀏覽 129
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  有码一区二区三区 | 在线h片 | 欧美色乱论视频 | 韩国一级一级免费 | 激情无套内射无码视频 |