Repository navigation
Labels
BugA bug in TypeScriptA bug in TypeScriptDomain: lib.d.tsThe issue relates to the different libraries shipped with TypeScriptThe issue relates to the different libraries shipped with TypeScript
Milestone
Description
(Moved from rom microsoft/TypeScript-DOM-lib-generator#1562)
I am using TypeScript 5.0.4.
I have noticed the typing of String.replace seem oddly convoluted.
From lib.es5.d.ts:
interface String {
replace(searchValue: string | RegExp, replaceValue: string): string;
replace(searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => string): string;
}From lib.es2015.symbol.wellknown.d.ts:
interface String {
replace(searchValue: { [Symbol.replace](string: string, replaceValue: string): string; }, replaceValue: string): string;
replace(searchValue: { [Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string; }, replacer: (substring: string, ...args: any[]) => string): string;
}Like the first parameter is declared as an union, I would expect the second to be the same, at least in the lib.es5 version.
Notably, this makes the following code not compile:
// The second argument is an union of replaceValue and replacer from lib.es5
const replacementSteps: ([RegExp, string | ((substring: string, ...args: any[]) => string)])[] = [
[/(a|b)/gi, "a"],
[/(c|d)/gi, match => match.toUpperCase()],
];
let myString = "abcdef";
for (const [searchValue, replacement] of replacementSteps)
myString = myString.replace(searchValue, replacement); // TS2345 - the second parameter is considered invalidBy adding this into my declaration, the code works:
declare interface String {
replace(searchValue: string | RegExp, replaceValue: string | ((substring: string, ...args: any[]) => string)): string;
}I cannot propose a solution other than my last hack, and of course the variants with Symbol would have to be taken into account. Please consider this just a note.
See also this: #54223
Reacted by Ryan Cavanaugh and electrovir
Reacted by Copilot
Metadata
Metadata
Labels
BugA bug in TypeScriptA bug in TypeScriptDomain: lib.d.tsThe issue relates to the different libraries shipped with TypeScriptThe issue relates to the different libraries shipped with TypeScript
Activity
RyanCavanaugh commentedon May 26, 2023
I believe the use of overloads here instead of a union was a holdover from when union types couldn't provide contextual types, or maybe even when we didn't have unions at all. I think this can be updated without breaking anything.
graphemecluster commentedon Sep 9, 2023
I am happy to modify #50452 to fix this.
jwasnoggin commentedon Jan 19, 2024
This definition allows the use of a union while preserving the
Symbol.replacebit:electrovir commentedon Oct 6, 2025
The current implementation also blocks any
replaceValueparameter that is a union of the two available types:throws:
playground link
RyanCavanaugh commentedon Sep 19, 2026
String.prototype.replaceaccepts either a replacement string or a replacement function at runtime, but the separatelib.d.tsoverloads reject a value whose type is the union of those two forms. This still reports TS2769 in TypeScript 5.0.4, 6.0.3, and the current native build.