Typescript: increment number type

Viewed 2404

Is it possible from number type T to get number type Y that has value of T+1.

type one = 1

type Increment<T extends number> = ???

type two = Increment<one> // 2

P.S. Currently, I have hardcoded interface of incremented values, but the problem is hardcoded and hence limited:

export type IncrementMap = {
    0: 1,
    1: 2,
    2: 3,
3 Answers

I would just hardcode it like this:

type Increment<N extends number> = [
  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,50,51,52,53,54, // as far as you need
  ...number[] // bail out with number
][N]

type Zero = 0
type One = Increment<Zero> // 1
type Two = Increment<One>  // 2

type WhoKnows = Increment<12345>; // number

As I said in the other comments, there's currently no great support for this kind of naturally recursive type. I would love it if it were supported, but it's not there. In practice I've found that if something can handle tuples up to length 20 or so it's good enough, but your experience may differ.

Anyway, if anyone does come up with a solution here that isn't hardcoded but also works and performs well for arbitrary numbers (where Increment<123456789> will evaluate to 123456790) I'd be interested to see it. Maybe one day in the future it will be part of the language.

Hope that helps; good luck!

This solution is not hard coded but isn't useful due to TypeScript's recursion limits. When I've tested it, it does not handle Number2Nat greater than 45.

type SomeNat = [...unknown[]];
type Zero = [];
type Succ<N extends SomeNat> = [...N, unknown];
type Nat2Number<N extends SomeNat> = N["length"];
type Dec<N extends SomeNat> = N extends [unknown, ...infer T] ? T : never;
type Add<N extends SomeNat, M extends SomeNat> = [...N, ...M];
type Sub<N extends SomeNat, M extends SomeNat> = M extends Zero ? N : Sub<Dec<N>, Dec<M>>;
type Number2Nat<I extends number, N extends SomeNat = Zero> = I extends Nat2Number<N> ? N : Number2Nat<I, Succ<N>>;

A slightly different solution. But with the same limitations of 1000 recursive calls

type Arr<N extends number, T extends any[] = []> = T['length'] extends N ? T : Arr<N, [...T, any]>

type Inc<N extends number> = [...Arr<N>, any]['length']

type I20 = Inc<19>
Related