您好,登錄后才能下訂單哦!
這篇文章主要介紹了TypeScript類型實現加減乘除的方法是什么的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇TypeScript類型實現加減乘除的方法是什么文章都會有所收獲,下面我們一起來看看吧。
在網上看到這道題目:請用TS類型實現整除?
type A = Divide<1, 0> // never type B = Divide<4, 2> // 2 type C = Divide<10, 3> // 3
看完題目,我真的毫無思路,TS類型還能實現除法???一臉懵逼的我認真地研究了一位叫做 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類型沒有直接提供數字的加減乘除,所以這位大佬的減法和整除都是通過數組長度計數來實現的。我平時體操練習很少,在沒看他的解答前,我永遠不會想到還能這么玩兒。
如果要實現98%10,假設A是98,B是10,讓A一直減B,直到A小于B,無法繼續再減,就能得到整除的結果。
A能減去9次B,每次進行減10的時候,往S(用來計數的數組,初始值為空數組)里面push一個元素。A減去9次10后,S數組的長度是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,我們執行A-B,然后我們給S數組push一個元素,再次計算Divide
接下來,讓我們開始逐個分析。
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數組
接下來舉例來看:
type res = SmallerThan<3,2> // 首先S['length']=0 ,所以不等于A和B,此時將any推入數組,S數組變成[any] // 接下來S['length'] =1,還是B等于A和B,此時繼續將A放入數組,S數組變成[any,any] // 此時S['length'] = 2,所以得出S的長度等于B,返回false
總之,S的長度是一次一次的累加的,先等于誰的長度,誰就更小。 如果S的長度先等于B的長度,那么就是A>B
。如果S的長度先等于A的長度,就是A<B
。
作用是將數字轉成數組,且數組的長度等于數字的大小
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進去
顧名思義,獲取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轉換長度為20的數組,B轉換成長度為10的數組,然后讓ts自己去infer,A的長度等于B的長度加上多少長度的數組,然后返回R的長度
前面已經實現了整除和減法,本著練習的態度,讓我們再實現一下乘法和加法。
仿照前面的Subtract,不難實現:
type Add<A extends number, B extends number > = [...Tuple<A>,...Tuple<B>] extends [... infer T] ? T['length']:never
接下來,讓我們實現一下乘法:
5*6
可以看作,5+5+5+5+5+5。
A*B
,也就是A要累加自己B次。如果我們每進行一次加法,就讓被乘數B減一,直到被乘數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會報遞歸可能是無限的
關于“TypeScript類型實現加減乘除的方法是什么”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“TypeScript類型實現加減乘除的方法是什么”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。