Skip to content

Commit cfea505

Browse files
authored
GreaterThan / LessThan / GreaterThanOrEqual / LessThanOrEqual: Fix behavior with the number type (#1363)
1 parent 8e9af4c commit cfea505

File tree

8 files changed

+94
-12
lines changed

8 files changed

+94
-12
lines changed

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,25 @@ type B = GreaterThanOrEqual<1, 1>;
1616
type C = GreaterThanOrEqual<1, 5>;
1717
//=> false
1818
```
19+
20+
Note: If either argument is the non-literal `number` type, the result is `boolean`.
21+
22+
@example
23+
```
24+
import type {GreaterThanOrEqual} from 'type-fest';
25+
26+
type A = GreaterThanOrEqual<number, 1>;
27+
//=> boolean
28+
29+
type B = GreaterThanOrEqual<1, number>;
30+
//=> boolean
31+
32+
type C = GreaterThanOrEqual<number, number>;
33+
//=> boolean
34+
```
1935
*/
2036
export type GreaterThanOrEqual<A extends number, B extends number> = number extends A | B
21-
? never
37+
? boolean
2238
: A extends number // For distributing `A`
2339
? B extends number // For distributing `B`
2440
? A extends B

source/greater-than.d.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,28 @@ type B = GreaterThan<1, 1>;
2020
type C = GreaterThan<1, 5>;
2121
//=> false
2222
```
23+
24+
Note: If either argument is the non-literal `number` type, the result is `boolean`.
25+
26+
@example
27+
```
28+
import type {GreaterThan} from 'type-fest';
29+
30+
type A = GreaterThan<number, 1>;
31+
//=> boolean
32+
33+
type B = GreaterThan<1, number>;
34+
//=> boolean
35+
36+
type C = GreaterThan<number, number>;
37+
//=> boolean
38+
```
2339
*/
2440
export type GreaterThan<A extends number, B extends number> =
2541
A extends number // For distributing `A`
2642
? B extends number // For distributing `B`
2743
? number extends A | B
28-
? never
44+
? boolean
2945
: [
3046
IsEqual<A, PositiveInfinity>, IsEqual<A, NegativeInfinity>,
3147
IsEqual<B, PositiveInfinity>, IsEqual<B, NegativeInfinity>,

source/less-than-or-equal.d.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,28 @@ type B = LessThanOrEqual<1, 1>;
1616
type C = LessThanOrEqual<1, 5>;
1717
//=> true
1818
```
19+
20+
Note: If either argument is the non-literal `number` type, the result is `boolean`.
21+
22+
@example
23+
```
24+
import type {LessThanOrEqual} from 'type-fest';
25+
26+
type A = LessThanOrEqual<number, 1>;
27+
//=> boolean
28+
29+
type B = LessThanOrEqual<1, number>;
30+
//=> boolean
31+
32+
type C = LessThanOrEqual<number, number>;
33+
//=> boolean
34+
```
1935
*/
20-
export type LessThanOrEqual<A extends number, B extends number> = number extends A | B
21-
? never
22-
: GreaterThan<A, B> extends true ? false : true;
36+
export type LessThanOrEqual<A extends number, B extends number> =
37+
GreaterThan<A, B> extends infer Result
38+
? Result extends true
39+
? false
40+
: true
41+
: never; // Should never happen
2342

2443
export {};

source/less-than.d.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,25 @@ type B = LessThan<1, 1>;
1616
type C = LessThan<1, 5>;
1717
//=> true
1818
```
19+
20+
Note: If either argument is the non-literal `number` type, the result is `boolean`.
21+
22+
@example
23+
```
24+
import type {LessThan} from 'type-fest';
25+
26+
type A = LessThan<number, 1>;
27+
//=> boolean
28+
29+
type B = LessThan<1, number>;
30+
//=> boolean
31+
32+
type C = LessThan<number, number>;
33+
//=> boolean
34+
```
1935
*/
20-
export type LessThan<A extends number, B extends number> = number extends A | B
21-
? never
22-
: GreaterThanOrEqual<A, B> extends infer Result
36+
export type LessThan<A extends number, B extends number> =
37+
GreaterThanOrEqual<A, B> extends infer Result
2338
? Result extends true
2439
? false
2540
: true

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ expectType<GreaterThanOrEqual<10, -2>>(true);
1111
expectType<GreaterThanOrEqual<2, 2>>(true);
1212
expectType<GreaterThanOrEqual<-2, -2>>(true);
1313
expectType<GreaterThanOrEqual<-2, -3>>(true);
14-
expectType<GreaterThanOrEqual<-2, number>>(never);
1514

1615
// === unions ===
1716
expectType<GreaterThanOrEqual<100 | 200, 50>>(true);
@@ -37,3 +36,8 @@ expectType<GreaterThanOrEqual<-999, NegativeInfinity>>(true);
3736
expectType<GreaterThanOrEqual<PositiveInfinity, PositiveInfinity>>(true);
3837
expectType<GreaterThanOrEqual<NegativeInfinity, NegativeInfinity>>(true);
3938
expectType<GreaterThanOrEqual<PositiveInfinity, NegativeInfinity>>(true);
39+
40+
// Non-literal `number`
41+
expectType<GreaterThanOrEqual<number, number>>({} as boolean);
42+
expectType<GreaterThanOrEqual<number, 1>>({} as boolean);
43+
expectType<GreaterThanOrEqual<1, number>>({} as boolean);

test-d/greater-than.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ expectType<GreaterThan<10, -2>>(true);
1111
expectType<GreaterThan<2, 2>>(false);
1212
expectType<GreaterThan<-2, -2>>(false);
1313
expectType<GreaterThan<-2, -3>>(true);
14-
expectType<GreaterThan<-2, number>>(never);
1514

1615
// === unions ===
1716
expectType<GreaterThan<100 | 200, 50>>(true);
@@ -35,3 +34,8 @@ expectType<GreaterThan<-999, NegativeInfinity>>(true);
3534
expectType<GreaterThan<PositiveInfinity, PositiveInfinity>>(false);
3635
expectType<GreaterThan<NegativeInfinity, NegativeInfinity>>(false);
3736
expectType<GreaterThan<PositiveInfinity, NegativeInfinity>>(true);
37+
38+
// Non-literal `number`
39+
expectType<GreaterThan<number, number>>({} as boolean);
40+
expectType<GreaterThan<number, 1>>({} as boolean);
41+
expectType<GreaterThan<1, number>>({} as boolean);

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ expectType<LessThanOrEqual<10, -2>>(false);
1111
expectType<LessThanOrEqual<2, 2>>(true);
1212
expectType<LessThanOrEqual<-2, -2>>(true);
1313
expectType<LessThanOrEqual<-2, -3>>(false);
14-
expectType<LessThanOrEqual<-2, number>>(never);
1514
expectType<LessThanOrEqual<PositiveInfinity, -999>>(false);
1615
expectType<LessThanOrEqual<PositiveInfinity, 999>>(false);
1716
expectType<LessThanOrEqual<999, PositiveInfinity>>(true);
@@ -20,3 +19,8 @@ expectType<LessThanOrEqual<-999, NegativeInfinity>>(false);
2019
expectType<LessThanOrEqual<PositiveInfinity, PositiveInfinity>>(true);
2120
expectType<LessThanOrEqual<NegativeInfinity, NegativeInfinity>>(true);
2221
expectType<LessThanOrEqual<PositiveInfinity, NegativeInfinity>>(false);
22+
23+
// Non-literal `number`
24+
expectType<LessThanOrEqual<number, number>>({} as boolean);
25+
expectType<LessThanOrEqual<number, 1>>({} as boolean);
26+
expectType<LessThanOrEqual<1, number>>({} as boolean);

test-d/less-than.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ expectType<LessThan<10, -2>>(false);
1111
expectType<LessThan<2, 2>>(false);
1212
expectType<LessThan<-2, -2>>(false);
1313
expectType<LessThan<-2, -3>>(false);
14-
expectType<LessThan<-2, number>>(never);
1514

1615
// === unions ===
1716
expectType<LessThan<10, 50 | 100>>(true);
@@ -36,3 +35,8 @@ expectType<LessThan<-999, NegativeInfinity>>(false);
3635
expectType<LessThan<PositiveInfinity, PositiveInfinity>>(false);
3736
expectType<LessThan<NegativeInfinity, NegativeInfinity>>(false);
3837
expectType<LessThan<PositiveInfinity, NegativeInfinity>>(false);
38+
39+
// Non-literal `number`
40+
expectType<LessThan<number, number>>({} as boolean);
41+
expectType<LessThan<number, 1>>({} as boolean);
42+
expectType<LessThan<1, number>>({} as boolean);

0 commit comments

Comments
 (0)