734 - Inclusive Range
Opened this issue · 0 comments
koSakano commented
type Tuple = Array<0>;
type Range = number[];
type Step = [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
];
/**
* Tail<[0, 0]> = [0].
* Tail<[]> = [].
*/
type Tail<T extends Tuple> = T extends [unknown, ...infer Rest] ? Rest : [];
type Next = { current: Tuple; added: Range };
type LowerAndHigher = { lower: Tuple; higher: Tuple };
type UntypedDoStep<
Current extends Tuple,
Limit extends number,
Rest extends Tuple = Step,
Added extends Range = []
> = Rest extends []
? { current: Current; added: Added }
: Current['length'] extends Limit
? { current: Current; added: Added }
: UntypedDoStep<[0, ...Current], Limit, Tail<Rest>, [...Added, Current['length']]>;
/**
* DoStep<[], 4> = { current: [0, 0, 0, 0], added: [0, 1, 2, 3] }.
*/
type DoStep<
Current extends Tuple,
Limit extends number,
N = UntypedDoStep<Current, Limit>
> = N extends Next ? N : never;
type UntypedLowerTuples<
Lower extends number,
Higher extends number,
L extends Tuple = [],
H extends Tuple = []
> = L['length'] extends Lower
? { lower: L; higher: H }
: H['length'] extends Higher
? { lower: L; higher: H }
: UntypedLowerTuples<Lower, Higher, DoStep<L, Lower>['current'], DoStep<H, Higher>['current']>;
/**
* LowerTuples<3, 4> = { lower: [0, 0, 0], higher: [0, 0, 0, 0] }.
*/
type LowerTuples<
Lower extends number,
Higher extends number,
R = UntypedLowerTuples<Lower, Higher>
> = R extends LowerAndHigher ? R : never;
/**
* GreaterOrEqual<[0, 0], [0, 0]> = true.
* GreaterOrEqual<[0, 0], [0, 0, 0]> = false.
* GreaterOrEqual<[0, 0], [0]> = true.
* GreaterOrEqual<[], [0]> = false.
*/
type GreaterOrEqual<X extends Tuple, Y extends Tuple> = X extends [...Y, ...Tuple] ? true : false;
/**
* RangeFrom<[], 5> = [0, 1, 2, 3, 4, 5].
* RangeFrom<[0, 0], 6> = [2, 3, 4, 5, 6].
*/
type RangeFrom<
T extends Tuple,
Higher extends number,
R extends Range = [],
S extends Next = DoStep<T, Higher>
> = T['length'] extends Higher
? [...R, T['length']]
: RangeFrom<S['current'], Higher, [...R, ...S['added']]>;
type InclusiveRange<
Lower extends number,
Higher extends number,
Tuples extends LowerAndHigher = LowerTuples<Lower, Higher>
> = GreaterOrEqual<Tuples['higher'], Tuples['lower']> extends false
? []
: RangeFrom<Tuples['lower'], Higher>;