From ed6fa8824cba9853b717ca2573995d6ddf6dda4c Mon Sep 17 00:00:00 2001
From: Shiba <44804845+DeepDoge@users.noreply.github.com>
Date: Mon, 21 Aug 2023 08:51:06 +0000
Subject: [PATCH 1/7] [ReadonlyArray] `.at()` fix `undefined` issue
---
src/entrypoints/array-at.d.ts | 14 +++++++++-----
src/entrypoints/utils.d.ts | 9 ++++++++-
src/tests/array-at.ts | 6 ++----
3 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/src/entrypoints/array-at.d.ts b/src/entrypoints/array-at.d.ts
index 7ab95a2..f4a0dd7 100644
--- a/src/entrypoints/array-at.d.ts
+++ b/src/entrypoints/array-at.d.ts
@@ -1,9 +1,13 @@
///
interface ReadonlyArray {
- at (index: I): `${I}` extends `-${infer J extends number}`
- ? `${TSReset.Subtract}` extends `-${number}`
- ? undefined
- : this[TSReset.Subtract]
- : this[I]
+ at(
+ index: I
+ ): TSReset.Equal extends true
+ ? T | undefined
+ : `${I}` extends `-${infer J extends number}`
+ ? `${TSReset.Subtract}` extends `-${number}`
+ ? undefined
+ : this[TSReset.Subtract]
+ : this[I];
}
\ No newline at end of file
diff --git a/src/entrypoints/utils.d.ts b/src/entrypoints/utils.d.ts
index 9d69f0b..a9ad320 100644
--- a/src/entrypoints/utils.d.ts
+++ b/src/entrypoints/utils.d.ts
@@ -22,8 +22,15 @@ declare namespace TSReset {
type BuildTuple = T extends { length: L }
? T
: BuildTuple
-
+
type Subtract = BuildTuple extends [...(infer U), ...BuildTuple]
? Length
: never
+
+ type Equal = (() => T extends X ? 1 : 2) extends <
+ T,
+ >() => T extends Y ? 1 : 2
+ ? true
+ : false;
+ type NotEqual = true extends Equal ? false : true;
}
diff --git a/src/tests/array-at.ts b/src/tests/array-at.ts
index a2530d4..c02586c 100644
--- a/src/tests/array-at.ts
+++ b/src/tests/array-at.ts
@@ -32,11 +32,9 @@ doNotExecute(async () => {
doNotExecute(async () => {
const arr = [false, 1, '2'] as const;
- const index: number = 1
+ const index = 1 as number
const a = arr.at(index)
- // WARN: with `"strictNullChecks": true,` the correct type here should include `undefined`
- // but the current implementation does not type this as including `undefined`
type tests = [
- Expect>,
+ Expect>,
]
});
\ No newline at end of file
From c21f78c2fa97586f3d7f50540ae9d06e212c40fe Mon Sep 17 00:00:00 2001
From: Shiba <44804845+DeepDoge@users.noreply.github.com>
Date: Mon, 21 Aug 2023 10:08:35 +0000
Subject: [PATCH 2/7] Fixed Subtract utils type, now works with unions
---
src/entrypoints/utils.d.ts | 52 ++++++++++++++++----------------------
src/tests/array-at.ts | 26 +++++++++++++++++++
2 files changed, 48 insertions(+), 30 deletions(-)
diff --git a/src/entrypoints/utils.d.ts b/src/entrypoints/utils.d.ts
index a9ad320..91438e1 100644
--- a/src/entrypoints/utils.d.ts
+++ b/src/entrypoints/utils.d.ts
@@ -1,36 +1,28 @@
declare namespace TSReset {
- type NonFalsy = T extends false | 0 | "" | null | undefined | 0n
- ? never
- : T;
+ type NonFalsy = T extends false | 0 | "" | null | undefined | 0n ? never : T
- type WidenLiteral = T extends string
- ? string
- : T extends number
- ? number
- : T extends boolean
- ? boolean
- : T extends bigint
- ? bigint
- : T extends symbol
- ? symbol
- : T;
+ type WidenLiteral = T extends string
+ ? string
+ : T extends number
+ ? number
+ : T extends boolean
+ ? boolean
+ : T extends bigint
+ ? bigint
+ : T extends symbol
+ ? symbol
+ : T
- type Length = T extends { length: infer L }
- ? L
- : never
+ type BuildTuple = T extends { length: L } ? T : BuildTuple
- type BuildTuple = T extends { length: L }
- ? T
- : BuildTuple
+ type Subtract = A extends number
+ ? B extends number
+ ? BuildTuple extends [...infer U, ...BuildTuple]
+ ? U["length"]
+ : never
+ : never
+ : never
- type Subtract = BuildTuple extends [...(infer U), ...BuildTuple]
- ? Length
- : never
-
- type Equal = (() => T extends X ? 1 : 2) extends <
- T,
- >() => T extends Y ? 1 : 2
- ? true
- : false;
- type NotEqual = true extends Equal ? false : true;
+ type Equal = (() => T extends X ? 1 : 2) extends () => T extends Y ? 1 : 2 ? true : false
+ type NotEqual = true extends Equal ? false : true
}
diff --git a/src/tests/array-at.ts b/src/tests/array-at.ts
index c02586c..d202ab0 100644
--- a/src/tests/array-at.ts
+++ b/src/tests/array-at.ts
@@ -30,6 +30,32 @@ doNotExecute(async () => {
]
});
+doNotExecute(async () => {
+ const arr = [false, 1, '2'] as const;
+
+ function index() {
+ return Math.random() > 0.5 ? 0 : 1
+ }
+
+ const a = arr.at(index())
+ type tests = [
+ Expect>,
+ ]
+});
+
+doNotExecute(async () => {
+ const arr = [false, true, 1, '2'] as const;
+
+ function index() {
+ return Math.random() > 0.5 ? -1 : -2
+ }
+
+ const a = arr.at(index())
+ type tests = [
+ Expect>,
+ ]
+});
+
doNotExecute(async () => {
const arr = [false, 1, '2'] as const;
const index = 1 as number
From 8c520d0821c55167cadfdacad5d2c72f3395c464 Mon Sep 17 00:00:00 2001
From: Shiba <44804845+DeepDoge@users.noreply.github.com>
Date: Mon, 21 Aug 2023 10:11:05 +0000
Subject: [PATCH 3/7] prettier format
---
src/entrypoints/array-at.d.ts | 20 ++++++------
src/entrypoints/utils.d.ts | 54 ++++++++++++++++++-------------
src/tests/array-at.ts | 60 ++++++++++++++++-------------------
3 files changed, 69 insertions(+), 65 deletions(-)
diff --git a/src/entrypoints/array-at.d.ts b/src/entrypoints/array-at.d.ts
index f4a0dd7..4db6d9a 100644
--- a/src/entrypoints/array-at.d.ts
+++ b/src/entrypoints/array-at.d.ts
@@ -1,13 +1,13 @@
///
interface ReadonlyArray {
- at(
- index: I
- ): TSReset.Equal extends true
- ? T | undefined
- : `${I}` extends `-${infer J extends number}`
- ? `${TSReset.Subtract}` extends `-${number}`
- ? undefined
- : this[TSReset.Subtract]
- : this[I];
-}
\ No newline at end of file
+ at(
+ index: I,
+ ): TSReset.Equal extends true
+ ? T | undefined
+ : `${I}` extends `-${infer J extends number}`
+ ? `${TSReset.Subtract}` extends `-${number}`
+ ? undefined
+ : this[TSReset.Subtract]
+ : this[I];
+}
diff --git a/src/entrypoints/utils.d.ts b/src/entrypoints/utils.d.ts
index 91438e1..bca143e 100644
--- a/src/entrypoints/utils.d.ts
+++ b/src/entrypoints/utils.d.ts
@@ -1,28 +1,38 @@
declare namespace TSReset {
- type NonFalsy = T extends false | 0 | "" | null | undefined | 0n ? never : T
+ type NonFalsy = T extends false | 0 | "" | null | undefined | 0n
+ ? never
+ : T;
- type WidenLiteral = T extends string
- ? string
- : T extends number
- ? number
- : T extends boolean
- ? boolean
- : T extends bigint
- ? bigint
- : T extends symbol
- ? symbol
- : T
+ type WidenLiteral = T extends string
+ ? string
+ : T extends number
+ ? number
+ : T extends boolean
+ ? boolean
+ : T extends bigint
+ ? bigint
+ : T extends symbol
+ ? symbol
+ : T;
- type BuildTuple = T extends { length: L } ? T : BuildTuple
+ type BuildTuple = T extends {
+ length: L;
+ }
+ ? T
+ : BuildTuple;
- type Subtract = A extends number
- ? B extends number
- ? BuildTuple extends [...infer U, ...BuildTuple]
- ? U["length"]
- : never
- : never
- : never
+ type Subtract = A extends number
+ ? B extends number
+ ? BuildTuple extends [...infer U, ...BuildTuple]
+ ? U["length"]
+ : never
+ : never
+ : never;
- type Equal = (() => T extends X ? 1 : 2) extends () => T extends Y ? 1 : 2 ? true : false
- type NotEqual = true extends Equal ? false : true
+ type Equal = (() => T extends X ? 1 : 2) extends () => T extends Y
+ ? 1
+ : 2
+ ? true
+ : false;
+ type NotEqual = true extends Equal ? false : true;
}
diff --git a/src/tests/array-at.ts b/src/tests/array-at.ts
index d202ab0..0bdd48d 100644
--- a/src/tests/array-at.ts
+++ b/src/tests/array-at.ts
@@ -1,66 +1,60 @@
import { doNotExecute, Equal, Expect } from "./utils";
doNotExecute(async () => {
- const arr = [false, 1, '2'] as const;
+ const arr = [false, 1, "2"] as const;
- const a = arr.at(0)
- const b = arr.at(1)
- const c = arr.at(2)
- const d = arr.at(3)
+ const a = arr.at(0);
+ const b = arr.at(1);
+ const c = arr.at(2);
+ const d = arr.at(3);
type tests = [
Expect>,
Expect>,
- Expect>,
+ Expect>,
Expect>,
- ]
+ ];
});
doNotExecute(async () => {
- const arr = [false, 1, '2'] as const;
+ const arr = [false, 1, "2"] as const;
- const a = arr.at(-1)
- const b = arr.at(-2)
- const c = arr.at(-3)
- const d = arr.at(-4)
+ const a = arr.at(-1);
+ const b = arr.at(-2);
+ const c = arr.at(-3);
+ const d = arr.at(-4);
type tests = [
- Expect>,
+ Expect>,
Expect>,
Expect>,
Expect>,
- ]
+ ];
});
doNotExecute(async () => {
- const arr = [false, 1, '2'] as const;
+ const arr = [false, 1, "2"] as const;
function index() {
- return Math.random() > 0.5 ? 0 : 1
+ return Math.random() > 0.5 ? 0 : 1;
}
- const a = arr.at(index())
- type tests = [
- Expect>,
- ]
+ const a = arr.at(index());
+ type tests = [Expect>];
});
doNotExecute(async () => {
- const arr = [false, true, 1, '2'] as const;
+ const arr = [false, true, 1, "2"] as const;
function index() {
- return Math.random() > 0.5 ? -1 : -2
+ return Math.random() > 0.5 ? -1 : -2;
}
- const a = arr.at(index())
- type tests = [
- Expect>,
- ]
+ const a = arr.at(index());
+ type tests = [Expect>];
});
doNotExecute(async () => {
- const arr = [false, 1, '2'] as const;
- const index = 1 as number
- const a = arr.at(index)
- type tests = [
- Expect>,
- ]
-});
\ No newline at end of file
+ const arr = [false, 1, "2"] as const;
+ const index = 1 as number;
+ const a = arr.at(index);
+ type tests = [Expect>];
+});
From 06ac7ee5eb44e918689977a4a901803768b89730 Mon Sep 17 00:00:00 2001
From: Shiba <44804845+DeepDoge@users.noreply.github.com>
Date: Mon, 21 Aug 2023 10:17:01 +0000
Subject: [PATCH 4/7] Added comment explaning why Subtract is the way its
---
src/entrypoints/utils.d.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/entrypoints/utils.d.ts b/src/entrypoints/utils.d.ts
index bca143e..6ec23aa 100644
--- a/src/entrypoints/utils.d.ts
+++ b/src/entrypoints/utils.d.ts
@@ -21,6 +21,7 @@ declare namespace TSReset {
? T
: BuildTuple;
+ // Extra `A extends number` and `B extends number` needed for union types to work Such as Subtract<10 | 20, 1>
type Subtract = A extends number
? B extends number
? BuildTuple extends [...infer U, ...BuildTuple]
From 95fef7a51cc701a9623b4b669a9194f03a701689 Mon Sep 17 00:00:00 2001
From: Shiba <44804845+DeepDoge@users.noreply.github.com>
Date: Mon, 21 Aug 2023 10:47:15 +0000
Subject: [PATCH 5/7] [ReadonlyArray] `.at()` handled floats
---
src/entrypoints/array-at.d.ts | 17 ++++++++++++-----
src/tests/array-at.ts | 4 ++++
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/src/entrypoints/array-at.d.ts b/src/entrypoints/array-at.d.ts
index 4db6d9a..3dda71d 100644
--- a/src/entrypoints/array-at.d.ts
+++ b/src/entrypoints/array-at.d.ts
@@ -1,13 +1,20 @@
///
interface ReadonlyArray {
- at(
- index: I,
+ at<
+ const N extends number,
+ I extends number = `${N}` extends `${infer J extends number}.${number}`
+ ? J
+ : N,
+ >(
+ index: N,
): TSReset.Equal extends true
? T | undefined
: `${I}` extends `-${infer J extends number}`
- ? `${TSReset.Subtract}` extends `-${number}`
- ? undefined
- : this[TSReset.Subtract]
+ ? TSReset.Subtract extends infer K extends number
+ ? [K] extends [never]
+ ? undefined
+ : this[K]
+ : undefined
: this[I];
}
diff --git a/src/tests/array-at.ts b/src/tests/array-at.ts
index 0bdd48d..9af5667 100644
--- a/src/tests/array-at.ts
+++ b/src/tests/array-at.ts
@@ -7,11 +7,13 @@ doNotExecute(async () => {
const b = arr.at(1);
const c = arr.at(2);
const d = arr.at(3);
+ const e = arr.at(1.5);
type tests = [
Expect>,
Expect>,
Expect>,
Expect>,
+ Expect>,
];
});
@@ -22,11 +24,13 @@ doNotExecute(async () => {
const b = arr.at(-2);
const c = arr.at(-3);
const d = arr.at(-4);
+ const e = arr.at(-1.5);
type tests = [
Expect>,
Expect>,
Expect>,
Expect>,
+ Expect>,
];
});
From ab41585e0155b997ebd3d2de703d5b1e087e3baf Mon Sep 17 00:00:00 2001
From: Shiba <44804845+DeepDoge@users.noreply.github.com>
Date: Mon, 21 Aug 2023 10:54:05 +0000
Subject: [PATCH 6/7] [ReadonlyArray] `.at()` Reverted some changes
---
src/entrypoints/array-at.d.ts | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/src/entrypoints/array-at.d.ts b/src/entrypoints/array-at.d.ts
index 3dda71d..ae1afb8 100644
--- a/src/entrypoints/array-at.d.ts
+++ b/src/entrypoints/array-at.d.ts
@@ -11,10 +11,8 @@ interface ReadonlyArray {
): TSReset.Equal extends true
? T | undefined
: `${I}` extends `-${infer J extends number}`
- ? TSReset.Subtract extends infer K extends number
- ? [K] extends [never]
- ? undefined
- : this[K]
- : undefined
+ ? `${TSReset.Subtract}` extends `-${number}`
+ ? undefined
+ : this[TSReset.Subtract]
: this[I];
}
From 064d896e71f3aa059a783a0f1a0a34d96474dda2 Mon Sep 17 00:00:00 2001
From: Shiba <44804845+DeepDoge@users.noreply.github.com>
Date: Mon, 21 Aug 2023 21:56:47 +0000
Subject: [PATCH 7/7] [ReadonlyArray] `.at()` test refactor
---
src/tests/array-at.ts | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/src/tests/array-at.ts b/src/tests/array-at.ts
index 9af5667..22a5d10 100644
--- a/src/tests/array-at.ts
+++ b/src/tests/array-at.ts
@@ -37,22 +37,18 @@ doNotExecute(async () => {
doNotExecute(async () => {
const arr = [false, 1, "2"] as const;
- function index() {
- return Math.random() > 0.5 ? 0 : 1;
- }
+ const index = 0 as 0 | 1
- const a = arr.at(index());
+ const a = arr.at(index);
type tests = [Expect>];
});
doNotExecute(async () => {
const arr = [false, true, 1, "2"] as const;
- function index() {
- return Math.random() > 0.5 ? -1 : -2;
- }
+ const index = -1 as -1 | -2
- const a = arr.at(index());
+ const a = arr.at(index);
type tests = [Expect>];
});