C# String extensions to TypeScript prototype extensions
Extending a base type with additional methods

Technical Director at Luminary. Umbraco 3x MVP.
Search for a command to run...
Extending a base type with additional methods

Technical Director at Luminary. Umbraco 3x MVP.
No comments yet. Be the first to comment.
My trials, tribulations and tips as I learn TypeScript (or try to write C# in JavaScript)
How not to extend an Array in TypeScript
Instructions

How does this even compute? What has digging a trench have to do with Software Engineering and building products?

My workplace Luminary turned 24 on 1-July-2023.

Headless in Umbraco core

Automate meeting host rotations within your team with some smarts

Microsoft C# extension methods is a great way to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.
I needed two extension methods to do the following:
So I wrote my C# extension methods as follows:
public static class StringExtensions {
public static bool ToBool(this string value){
return value.ToLower() == "yes";
}
public static DateTime ToDate(this string value){
return DateTime.TryParse(value, out DateTime result)
? result : DateTime.MinValue;
}
}
You can see a working .NET Fiddle below:
So I wrote the equivalent extensions in the TypeScript playground
...
String.prototype.toBoolean = function () {
return this.toLowerCase() === "yes";
};
String.prototype.toDate = function () {
return this != "" ? new Date(Date.parse(this.toString())) :
new Date("01-Jan-2001");
}
...
Interesting, this code gives a compile time error. But still runs 😱
Property 'toBoolean' does not exist on type 'String'.
Property 'toDate' does not exist on type 'String'.
I needed to declare an interface for String first as you can see in my playground script and the code below:
interface String {
toBoolean(): boolean;
toDate(): Date | undefined;
}
String.prototype.toBoolean = function () {
return this.toLowerCase() === "yes";
};
String.prototype.toDate = function () {
return this != "" ? new Date(Date.parse(this.toString())) :
new Date("01-Jan-2001");
}
...
This TypeScript code compiled and ran without any issues. Note that when you do this in your local environment, add the interface code to a String.d.ts file to keep it neat.
This SO Answer helped me to write the code.
This SO Answer gives the explanation as to why adding an interface works:
Declaring the new member so it can pass type-checking. You need to declare an interface with the same name as the constructor/class you want to modify and put it under the correct declared namespace/module. This is called scope augmentation.