type-challenges:MinusOne

34 阅读1分钟

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

答案已经变成我快看不懂的样子了.....,已经变成纯抄题和抄答案,然后自己理解了,我是个废物......呜呜呜呜。