I have a string const where I have to replace two words, like this:
public static readonly MY_STRING: string = 'page={0}&id={1}';
0 and 1 have to be replaced with other strings. I have read about String.format in different answers, where they suggest to supply an implementation like this:
if (!String.prototype.format) {
String.prototype.format = function() {
var args = arguments;
return this.replace(/{(\d+)}/g, function(match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
}
but when I do String.format
it tells me
Property 'format' does not exist on type 'String'
What is the proper way to use String interpolation/substitution in this case? With format I'd do something like this:
MY_STRING.format(page, id)
How can I achieve this?
It is considered bad practice to modify native prototypes like String
. Since there's no standard or agreed-upon format()
method for strings in JavaScript, adding your own could lead to unexpected behavior in any code that runs in the same runtime. Your implementation even checks for an existing String.prototype.format
first, which means if someone gets there first with a different implementation, then you could be the one with unexpected behavior.
There's absolutely nothing wrong with just having a stringFormat
function sitting around that you use, like this:
function stringFormat(template: string, ...args: any[]) {
return template.replace(/{(\d+)}/g, function (match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
const myString: string = 'page={0}&id={1}';
const formattedWithFormat = stringFormat(myString, 123, 456);
console.log(formattedWithFormat); // page=123&id=456
Also, JavaScript has template literals which provide essentially the same functionality:
const myTemplate = (page: number, id: number) => `page=${page}&id=${id}`;
const formattedWithTemplate = myTemplate(123, 456);
console.log(formattedWithTemplate); // page=123&id=456
If you are intent on modifying the prototype of String
and the previous warnings didn't dissuade you, then you could use the global augmentation or module augmentation approach to allow TypeScript to recognize that you expect string
values to have a format()
method:
/* 🐉 here be dragons 🐲 */
interface String {
format(...args: any[]): string;
}
String.prototype.format = function (...args) { return stringFormat(String(this), ...args) };
console.log(myString.format(123, 789)); // page=123&id=789
but hopefully you will use one of the other solutions.
Okay, hope that helps; good luck!