您好,登錄后才能下訂單哦!
這篇文章主要介紹了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)不會想到還能這么玩兒。
如果要實現(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用于判斷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
。
作用是將數(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)去
顧名思義,獲取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è)資訊頻道。
免責(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)容。