Skip to content

Commit afd809a

Browse files
authored
LessThan / GreaterThan / GreaterThanOrEqual: Fix behaviour with unions (#1116)
1 parent 8c154e9 commit afd809a

File tree

5 files changed

+81
-28
lines changed

5 files changed

+81
-28
lines changed

source/greater-than.d.ts

+32-27
Original file line numberDiff line numberDiff line change
@@ -21,31 +21,36 @@ GreaterThan<1, 5>;
2121
//=> false
2222
```
2323
*/
24-
export type GreaterThan<A extends number, B extends number> = number extends A | B
25-
? never
26-
: [
27-
IsEqual<A, PositiveInfinity>, IsEqual<A, NegativeInfinity>,
28-
IsEqual<B, PositiveInfinity>, IsEqual<B, NegativeInfinity>,
29-
] extends infer R extends [boolean, boolean, boolean, boolean]
30-
? Or<
31-
And<IsEqual<R[0], true>, IsEqual<R[2], false>>,
32-
And<IsEqual<R[3], true>, IsEqual<R[1], false>>
33-
> extends true
34-
? true
35-
: Or<
36-
And<IsEqual<R[1], true>, IsEqual<R[3], false>>,
37-
And<IsEqual<R[2], true>, IsEqual<R[0], false>>
38-
> extends true
39-
? false
40-
: true extends R[number]
41-
? false
42-
: [IsNegative<A>, IsNegative<B>] extends infer R extends [boolean, boolean]
43-
? [true, false] extends R
24+
export type GreaterThan<A extends number, B extends number> =
25+
A extends number // For distributing `A`
26+
? B extends number // For distributing `B`
27+
? number extends A | B
28+
? never
29+
: [
30+
IsEqual<A, PositiveInfinity>, IsEqual<A, NegativeInfinity>,
31+
IsEqual<B, PositiveInfinity>, IsEqual<B, NegativeInfinity>,
32+
] extends infer R extends [boolean, boolean, boolean, boolean]
33+
? Or<
34+
And<IsEqual<R[0], true>, IsEqual<R[2], false>>,
35+
And<IsEqual<R[3], true>, IsEqual<R[1], false>>
36+
> extends true
37+
? true
38+
: Or<
39+
And<IsEqual<R[1], true>, IsEqual<R[3], false>>,
40+
And<IsEqual<R[2], true>, IsEqual<R[0], false>>
41+
> extends true
4442
? false
45-
: [false, true] extends R
46-
? true
47-
: [false, false] extends R
48-
? PositiveNumericStringGt<`${A}`, `${B}`>
49-
: PositiveNumericStringGt<`${NumberAbsolute<B>}`, `${NumberAbsolute<A>}`>
50-
: never
51-
: never;
43+
: true extends R[number]
44+
? false
45+
: [IsNegative<A>, IsNegative<B>] extends infer R extends [boolean, boolean]
46+
? [true, false] extends R
47+
? false
48+
: [false, true] extends R
49+
? true
50+
: [false, false] extends R
51+
? PositiveNumericStringGt<`${A}`, `${B}`>
52+
: PositiveNumericStringGt<`${NumberAbsolute<B>}`, `${NumberAbsolute<A>}`>
53+
: never
54+
: never
55+
: never // Should never happen
56+
: never; // Should never happen

source/less-than.d.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,8 @@ LessThan<1, 5>;
1919
*/
2020
export type LessThan<A extends number, B extends number> = number extends A | B
2121
? never
22-
: GreaterThanOrEqual<A, B> extends true ? false : true;
22+
: GreaterThanOrEqual<A, B> extends infer Result
23+
? Result extends true
24+
? false
25+
: true
26+
: never; // Should never happen

test-d/greater-than-or-equal.ts

+15
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,21 @@ expectType<GreaterThanOrEqual<-2, -2>>(true);
1313
expectType<GreaterThanOrEqual<-2, -3>>(true);
1414
expectType<GreaterThanOrEqual<-2, number>>(never);
1515

16+
// === unions ===
17+
expectType<GreaterThanOrEqual<100 | 200, 50>>(true);
18+
expectType<GreaterThanOrEqual<25, -100 | -15 | 2 | 21>>(true);
19+
expectType<GreaterThanOrEqual<10 | 15, -5 | 10>>(true);
20+
21+
expectType<GreaterThanOrEqual<10, 50 | 100>>(false);
22+
expectType<GreaterThanOrEqual<50 | 25 | 0 | -16, 100>>(false);
23+
expectType<GreaterThanOrEqual<1 | 2, 3 | 4>>(false);
24+
25+
expectType<GreaterThanOrEqual<-10, -90 | 90>>({} as boolean);
26+
expectType<GreaterThanOrEqual<-16 | 16, 0>>({} as boolean);
27+
expectType<GreaterThanOrEqual<-4 | 45, 20 | 30>>({} as boolean);
28+
expectType<GreaterThanOrEqual<1 | -1 | 3, 0 | 2>>({} as boolean);
29+
expectType<GreaterThanOrEqual<1 | 2 | 3, 3 | 4>>({} as boolean);
30+
1631
expectType<GreaterThanOrEqual<PositiveInfinity, -999>>(true);
1732
expectType<GreaterThanOrEqual<PositiveInfinity, 999>>(true);
1833
expectType<GreaterThanOrEqual<999, PositiveInfinity>>(false);

test-d/greater-than.ts

+14
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,20 @@ expectType<GreaterThan<-2, -2>>(false);
1313
expectType<GreaterThan<-2, -3>>(true);
1414
expectType<GreaterThan<-2, number>>(never);
1515

16+
// === unions ===
17+
expectType<GreaterThan<100 | 200, 50>>(true);
18+
expectType<GreaterThan<25, -100 | -15 | 2 | 21>>(true);
19+
expectType<GreaterThan<10 | 15, -5 | 5>>(true);
20+
21+
expectType<GreaterThan<10, 50 | 100>>(false);
22+
expectType<GreaterThan<50 | 25 | 0 | -16, 100>>(false);
23+
expectType<GreaterThan<1 | 2 | 3, 3 | 4>>(false);
24+
25+
expectType<GreaterThan<-10, -90 | 90>>({} as boolean);
26+
expectType<GreaterThan<-16 | 16, 0>>({} as boolean);
27+
expectType<GreaterThan<-4 | 45, 20 | 30>>({} as boolean);
28+
expectType<GreaterThan<1 | -1 | 3, 0 | 2>>({} as boolean);
29+
1630
expectType<GreaterThan<PositiveInfinity, -999>>(true);
1731
expectType<GreaterThan<PositiveInfinity, 999>>(true);
1832
expectType<GreaterThan<999, PositiveInfinity>>(false);

test-d/less-than.ts

+15
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,21 @@ expectType<LessThan<2, 2>>(false);
1212
expectType<LessThan<-2, -2>>(false);
1313
expectType<LessThan<-2, -3>>(false);
1414
expectType<LessThan<-2, number>>(never);
15+
16+
// === unions ===
17+
expectType<LessThan<10, 50 | 100>>(true);
18+
expectType<LessThan<50 | 25 | 0 | -16, 100>>(true);
19+
expectType<LessThan<1 | 2, 3 | 4>>(true);
20+
21+
expectType<LessThan<100 | 200, 50>>(false);
22+
expectType<LessThan<25, -100 | -15 | 2 | 21>>(false);
23+
expectType<LessThan<10 | 15, -5 | 10>>(false);
24+
25+
expectType<LessThan<-10, -90 | 90>>({} as boolean);
26+
expectType<LessThan<-16 | 16, 0>>({} as boolean);
27+
expectType<LessThan<-4 | 45, 20 | 30>>({} as boolean);
28+
expectType<LessThan<1 | -1 | 3, 0 | 2>>({} as boolean);
29+
1530
expectType<LessThan<PositiveInfinity, -999>>(false);
1631
expectType<LessThan<PositiveInfinity, 999>>(false);
1732
expectType<LessThan<999, PositiveInfinity>>(true);

0 commit comments

Comments
 (0)