溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

TypeScript類型實現(xiàn)加減乘除的方法是什么

發(fā)布時間:2023-04-15 14:26:23 來源:億速云 閱讀:166 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹了TypeScript類型實現(xiàn)加減乘除的方法是什么的相關(guān)知識,內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇TypeScript類型實現(xiàn)加減乘除的方法是什么文章都會有所收獲,下面我們一起來看看吧。

    引言

    在網(wǎng)上看到這道題目:請用TS類型實現(xiàn)整除?

    type A = Divide<1, 0> // never
    type B = Divide<4, 2> // 2
    type C = Divide<10, 3> // 3

    看完題目,我真的毫無思路,TS類型還能實現(xiàn)除法???一臉懵逼的我認(rèn)真地研究了一位叫做  JoeYan大佬的解答:

    type Tuple<T extends number, U extends any[] = []> =
        U['length'] extends T ? U : Tuple<T, [...U, any]>
    type Subtract<
        A extends number,
        B extends number
    > = Tuple<A> extends [...Tuple<B>, ...infer R] ? R['length'] : never
    type SmallerThan<
        A extends number,
        B extends number,
        S extends any[] = []
    > = S['length'] extends B
        ? false
        : S['length'] extends A
        ? true
        : SmallerThan<A, B, [...S,A]>
    type Divide<A extends number, B extends number, S extends any[] = []> =
        B extends 0 ? never : SmallerThan<A, B> extends true ? S['length'] : Divide<Subtract<A, B>, B, [...S, any]>;
    type res = Divide<200, 10> // 20

    分析

    乍一看,真的驚呆了,但是一步一步分析,還是能夠看懂的,本文將整個研究的過程記錄了下來:

    TS類型沒有直接提供數(shù)字的加減乘除,所以這位大佬的減法和整除都是通過數(shù)組長度計數(shù)來實現(xiàn)的。我平時體操練習(xí)很少,在沒看他的解答前,我永遠(yuǎn)不會想到還能這么玩兒。

    Divide

    如果要實現(xiàn)98%10,假設(shè)A是98,B是10,讓A一直減B,直到A小于B,無法繼續(xù)再減,就能得到整除的結(jié)果。

    A能減去9次B,每次進(jìn)行減10的時候,往S(用來計數(shù)的數(shù)組,初始值為空數(shù)組)里面push一個元素。A減去9次10后,S數(shù)組的長度是9。此時A是8,B是10,A小于B,返回S的長度9。

    type Divide<A extends number, B extends number, S extends number[] = []> =
        B extends 0 ? never : SmallerThan<A, B> extends true ? S['length'] : Divide<Subtract<A, B>, B, [...S, any]>;

    上面這段代碼的字面意思是:

    • B是否為0,直接返回never

    • A如果小于B,返回S的長度

    • A如果大于B,我們執(zhí)行A-B,然后我們給S數(shù)組push一個元素,再次計算Divide

    接下來,讓我們開始逐個分析。

    SmallerThan

    SmallerThan用于判斷A是否小于B

    type res = SmallerThan<10,2>  // res為false
    type res = SmallerThan<2,20> // res為true
    type SmallerThan<
        A extends number,
        B extends number,
        S extends any[] = []
    > = S['length'] extends B
        ? false
        : S['length'] extends A
        ? true
        : SmallerThan<A, B, [...S,any]>

    字面上看起來是:

    • S的長度等于B,返回false

    • S的長度不等于B且S的長度等于A,返回true

    • S的長度不等于A和B,將any推入S數(shù)組

    接下來舉例來看:

    type res = SmallerThan<3,2>  
    // 首先S['length']=0 ,所以不等于A和B,此時將any推入數(shù)組,S數(shù)組變成[any]
    // 接下來S['length'] =1,還是B等于A和B,此時繼續(xù)將A放入數(shù)組,S數(shù)組變成[any,any]
    // 此時S['length'] = 2,所以得出S的長度等于B,返回false

    總之,S的長度是一次一次的累加的,先等于誰的長度,誰就更小。 如果S的長度先等于B的長度,那么就是A>B。如果S的長度先等于A的長度,就是A<B。

    Tuple

    作用是將數(shù)字轉(zhuǎn)成數(shù)組,且數(shù)組的長度等于數(shù)字的大小

    type Tuple<T extends number, U extends any[] = []> =
        U['length'] extends T ? U : Tuple<T, [...U, any]>
    type res4 = Tuple<3> // [any, any, any]‘
    // 基本上和上面的SmallerThan差不多,就是不夠長度,就push一個any進(jìn)去

    Subtract

    顧名思義,獲取A-B的值

    type Subtract<
        A extends number,
        B extends number
    > = Tuple<A> extends [...Tuple<B>, ...infer R] ? R : never
    type res3 = Subtract<10,8> // [any, any]
    type Subtract<
        A extends number,
        B extends number
    > = Tuple<A> extends [...Tuple<B>, ...infer R] ? R['length'] : never
    type res3 = Subtract<20,10> // 10
    // 一開始把A轉(zhuǎn)換長度為20的數(shù)組,B轉(zhuǎn)換成長度為10的數(shù)組,然后讓ts自己去infer,A的長度等于B的長度加上多少長度的數(shù)組,然后返回R的長度

    最后

    前面已經(jīng)實現(xiàn)了整除和減法,本著練習(xí)的態(tài)度,讓我們再實現(xiàn)一下乘法和加法。

    加法

    仿照前面的Subtract,不難實現(xiàn):

    type Add<A extends number, B extends number > = [...Tuple<A>,...Tuple<B>] extends [... infer T] ? T['length']:never

    乘法

    接下來,讓我們實現(xiàn)一下乘法:

    5*6 可以看作,5+5+5+5+5+5。

    A*B,也就是A要累加自己B次。如果我們每進(jìn)行一次加法,就讓被乘數(shù)B減一,直到被乘數(shù)B為0,也就完成了累加。

    type Tuple<T extends number, U extends any[] = []> =
        U['length'] extends T ? U : Tuple<T, [...U, any]>
    type Mutiply<A extends number, B extends number, S extends any[] = []> = B extends 0 ? S['length'] : Mutiply<A, Subtract<B, 1>, [...S, ...Tuple<A>]>
    type res = Mutiply<5,6> //30

    坑點

    type Tuple<T extends number, S extends any[] = []> = S['length'] extends T ? S : Tuple<T, [...S, any]> // 不報錯
    // type Tuple<T extends number, S extends any[] = []> = T extends S['length'] ? S : Tuple<T, [...S, any]> 
    // 不能寫成T extends S['length'],ts會報遞歸可能是無限的

    關(guān)于“TypeScript類型實現(xiàn)加減乘除的方法是什么”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“TypeScript類型實現(xiàn)加減乘除的方法是什么”知識都有一定的了解,大家如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI