summaryrefslogtreecommitdiff
path: root/src/lang/ts-lang/util/number.ts
blob: 2fa6d85a81f7810d964e19c336131b2a3600f65e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
export type NumberToArray<
  Number extends number,
  Carry extends readonly any[] = []
> = Number extends Carry["length"]
  ? Carry
  : NumberToArray<Number, [...Carry, any]>;

export type NumbersToArray<
  Numbers extends readonly number[],
  Carry extends readonly any[] = []
> = Numbers extends [
  infer Head extends number,
  ...infer Tail extends readonly number[]
]
  ? NumbersToArray<Tail, [...Carry, ...NumberToArray<Head>]>
  : Carry;

export type AddNumbers<Numbers extends readonly number[]> =
  NumbersToArray<Numbers> extends infer T extends readonly any[]
    ? T["length"]
    : never;

export type SubNumbersInternal<
  MS extends readonly unknown[],
  NS extends readonly unknown[]
> = MS extends readonly [...NS, ...infer Tail] ? Tail : never;

export type SubNumbers<M extends number, N extends number> = SubNumbersInternal<
  NumberToArray<M>,
  NumberToArray<N>
> extends infer T extends readonly any[]
  ? T["length"]
  : never;

export type MultiplyInner<
  N extends number,
  MS extends readonly any[],
  Carry extends number = 0
> = MS extends [infer Head extends number, ...infer Tail extends readonly any[]]
  ? MultiplyInner<N, Tail, AddNumbers<[Carry, N]>>
  : Carry;

export type Multiply<M extends number, N extends number> = MultiplyInner<
  M,
  NumberToArray<N>
>;

export type ExtractNumber<T extends any> =
  T extends `${infer Inner extends number}` ? Inner : never;