MinusOne
问题描述
给定一个正整数作为类型的参数,要求返回的类型是该数字减 1。
例如:
type Zero = MinusOne<1> // 0
type FiftyFour = MinusOne<55> // 54
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'
type cases = [
Expect<Equal<MinusOne<1>, 0>>,
Expect<Equal<MinusOne<55>, 54>>,
Expect<Equal<MinusOne<3>, 2>>,
Expect<Equal<MinusOne<100>, 99>>,
Expect<Equal<MinusOne<1101>, 1100>>,
Expect<Equal<MinusOne<0>, -1>>,
Expect<Equal<MinusOne<9_007_199_254_740_992>, 9_007_199_254_740_991>>
]
// ============= Your Code Here =============
// 答案1
type ParseInt<T extends string> = T extends `${infer Digit extends number}` ? Digit : never
type ReverseString<S extends string> = S extends `${infer First}${infer Rest}` ? `${ReverseString<Rest>}${First}` : ''
type RemoveLeadingZeros<S extends string> = S extends '0' ? S : S extends `${'0'}${infer R}` ? RemoveLeadingZeros<R> : S
type InternalMinusOne<S extends string> = S extends `${infer Digit extends number}${infer Rest}`
? Digit extends 0
? `9${InternalMinusOne<Rest>}`
: `${[9, 0, 1, 2, 3, 4, 5, 6, 7, 8][Digit]}${Rest}`
: never
type MinusOne<T extends number> = T extends 0
? -1
: ParseInt<RemoveLeadingZeros<ReverseString<InternalMinusOne<ReverseString<`${T}`>>>>>
// 答案2
// 将数字转为对应长度的数组 如将2 转换为 [null, null]
type DigitToArray<T extends number, R extends any[] = []> = R['length'] extends T ? R : DigitToArray<T, [...R, null]>
// 将数字(字符串)的每一位都转为对应长度的数组,如将 '23' 转换为 [[null, null], [null, null, null]]
type WholeDigitStringToArray<
T extends string,
Res extends any[][] = []
> = T extends `${infer A extends number}${infer R}` ? WholeDigitStringToArray<R, [...Res, DigitToArray<A>]> : Res
// 将数字的每一位都转为对应长度的数组,如将 23 转换为 [[null, null], [null, null, null]]
type WholeDigitToArray<T extends number> = WholeDigitStringToArray<`${T}`>
// 翻转数组(要从个位 - 十位 - 百位 依次去减一)
type MyReverse<T extends any[], Res extends any[] = []> = T extends [...infer A, infer R]
? MyReverse<A, [...Res, R]>
: Res
// 逐位减一,返回当前位减一的结果,及是否产生了借位
type MinusBitByBit<T extends any[]> = T extends [infer _, ...infer R] ? [R['length'], false] : [9, true]
// 将数组中的每一项展示为对应数组的长度 如将[[null, null], [null, null, null]] 转为 [2, 3]
type ArrayEveryToNumber<T extends any[][], Res extends any[] = []> = T extends [
infer A extends any[],
...infer R extends any[][]
]
? ArrayEveryToNumber<R, [...Res, A['length']]>
: Res
// 数组整体减一操作
type WholeArrayMinusOne<T extends any[], Res extends any[] = []> = T extends [
infer A extends any[],
...infer R extends any[]
]
? MinusBitByBit<A> extends [infer X, infer Y]
? Y extends true
? WholeArrayMinusOne<R, [...Res, X]>
: [...Res, X, ...ArrayEveryToNumber<R>]
: Res
: Res
// 将数组转为字符串
type ArrayToString<T extends any[], Res extends string = ''> = T extends [infer A extends number, ...infer R]
? ArrayToString<R, `${Res}${A}`>
: Res
// 将字符串转为数字
type StringToNumber<T extends string> = T extends 0
? 0
: T extends `0${infer A extends number}`
? A
: T extends `${infer F extends number}`
? F
: T
type MinusOne<T extends number> = T extends 0
? -1
: StringToNumber<ArrayToString<MyReverse<WholeArrayMinusOne<MyReverse<WholeDigitToArray<T>>>>>>
答案已经变成我快看不懂的样子了.....,已经变成纯抄题和抄答案,然后自己理解了,我是个废物......呜呜呜呜。