I am trying to rewrite some of my JavaScript code in TypeScript. Some of this code has references to an extension I added to the string object prototype.
String.prototype.format = function () {
var formatted = this;
for (var i = 0; i < arguments.length; i++) {
formatted = formatted.replace(
RegExp("\\{" + i + "\\}", 'g'), arguments[i].toString());
}
return formatted;
};
However adding this with type script has been quite challenging.
I have seen examples where you declare an extension of a basic interface then assign an function to the prototype to match the interface and provide your functionality. Like so...
interface String {
showString: () => string;
}
String.prototype.showString = (): string {
return this;
};
Except this errors because "_this is not defined..."
The other things I have tried is to create a new class to extend string...
export class MoreString extends string {
}
However this also does not work because you can only extend classes and string/String are not classes but built in types.
What is the simplest way to extend String and access my extension method?
I ended up running into another issue later in the day that made me see what was happening here. From the top, here it is...
TypeScript is built on top of JavaScript, so like @Nypan says JavaScript is valid TypeScript. Because of this the differences are very easy to overlook.
A JavaScript function like this references the scope that the function executes in with "this".
var f = function (postFix) {return this + postFix};
To add TypeScript syntax you would define types
var f = function (postFix: string): string {return this + postFix};
In both of these cases this refers to the scope of the function just like classic JavaScript. However, things change when we do this...
var f = (postFix: string): string {return this + postFix};
//or more correctly
var f = (postFix: string): string => {return this + postFix};
When you remove the function from in front of the parameters then it is no longer a classic function. It becomes a "Fat Arrow" function, apparently even with out using the "=>" syntax. In the examples above "this" now refers to the class that the function exists in like in C#.
In my attempt to assign a function to the prototype of string I omitted the function keyword so it was interpreted as a "Fat Arrow" function and tries to bind this to the scope of the class. However the function dose not exist in a class and causes the error "_this is not defined".
When I add the "function" keyword, the function is interpreted as I intended and works correctly.
interface String {
format: () => string;
}
String.prototype.format = function () : string {
var formatted = this;
for (var i = 0; i < arguments.length; i++) {
formatted = formatted.replace(
RegExp("\\{" + i + "\\}", 'g'), arguments[i].toString());
}
return formatted;
};
In exactly similiar case i do it like that:
interface String {
endsWith(str);
startsWith(str);
}
This is just to satisfy the compiler. You implement the methods exactly like in javascript.
Hope that helps.
I think that this is the same thing that stride was getting at but you simply extend it in javascript (javascript is valid typescript) and then interface the new functionality.
Short example:
String.prototype.myExtension = function () {
return this + " something."
};
interface String {
myExtension : () => string;
}
alert("test".myExtension());
You need to extend the String interface like this:
interface String {
stringFormat(...args: string[]): string;
}
and you need to implement like this
module Utilities {
String.prototype.stringFormat = function (): string {
var args = arguments;
return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (m, n) {
if (m == "{{") { return "{"; }
if (m == "}}") { return "}"; }
return args[n];
});
}
}
implementation source: Equivalent of String.format in jQuery
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With