From bcc5d034469f95f73c64cb0ef5d3f4a6d78d12c4 Mon Sep 17 00:00:00 2001 From: ASDAlexander77 Date: Mon, 5 Oct 2026 16:00:19 +0100 Subject: [PATCH] endsWith, startsWith and indexOf find an empty search string Each began with `if (!searchString)`, a null check written as a truthiness test. While the compiler took "" as true it let "" through, and the functions went on to give what JavaScript gives: endsWith("") and startsWith("") true, indexOf("") the position. With "" falsy (TypeScriptCompiler #509) the guard returned false / -1 for it. The guards are now `searchString == null`, which is the same test under either compiler, so this can land before or after the compiler change. lastIndexOf has the same guard, but it already returns `position` for "" a few lines later, so it is left alone. tests/string_empty_search.ts asserts each case. With the compiler fix and the old guards, it fails at endsWith(''). Co-Authored-By: Claude Opus 5.5 --- src/lib.ts | 9 ++++++--- tests/string_empty_search.ts | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 tests/string_empty_search.ts diff --git a/src/lib.ts b/src/lib.ts index 4e19ade..5fb035e 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -678,7 +678,8 @@ namespace __String { } export function endsWith(this: string, searchString: string, endPosition = this.length): boolean { - if (!searchString) + // a null check: "" is falsy, and an empty search string is found + if (searchString == null) { return false; } @@ -703,7 +704,8 @@ namespace __String { } export function indexOf(this: string, searchString: string, position = 0): int { - if (!searchString) + // a null check: "" is falsy, and an empty search string is found + if (searchString == null) { return -1; } @@ -989,7 +991,8 @@ namespace __String { } export function startsWith(this: string, searchString: string, position = 0): boolean { - if (!searchString) + // a null check: "" is falsy, and an empty search string is found + if (searchString == null) { return false; } diff --git a/tests/string_empty_search.ts b/tests/string_empty_search.ts new file mode 100644 index 0000000..2c2e00b --- /dev/null +++ b/tests/string_empty_search.ts @@ -0,0 +1,31 @@ +// an empty search string is found, as in JavaScript. The guard on it was `!searchString`, a null +// check written as truthiness: once "" was falsy (TypeScriptCompiler #509) it returned "not found". +function main() { + const s = "abc"; + + assert(s.endsWith(""), "endsWith('')"); + assert(s.endsWith("", 1), "endsWith('', 1)"); + assert(s.endsWith("bc"), "endsWith('bc')"); + assert(!s.endsWith("x"), "endsWith('x')"); + + assert(s.startsWith(""), "startsWith('')"); + assert(s.startsWith("", 3), "startsWith('', 3)"); + assert(s.startsWith("ab"), "startsWith('ab')"); + assert(!s.startsWith("x"), "startsWith('x')"); + + assert(s.indexOf("") == 0, "indexOf('')"); + assert(s.indexOf("", 2) == 2, "indexOf('', 2)"); + assert(s.indexOf("", 5) == 3, "indexOf('', 5)"); + assert(s.indexOf("c") == 2, "indexOf('c')"); + assert(s.indexOf("x") == -1, "indexOf('x')"); + + assert(s.lastIndexOf("") == 3, "lastIndexOf('')"); + assert(s.includes(""), "includes('')"); + + const empty = ""; + assert(empty.endsWith(""), "''.endsWith('')"); + assert(empty.startsWith(""), "''.startsWith('')"); + assert(empty.indexOf("") == 0, "''.indexOf('')"); + + console.log("ALL DONE"); +}