How to extend an existing TypeScript class without a subclass?
C# partial classes for TypeScript
Today’s we are going to investigate how to extend an existing TypeScript class freely, adding new methods in particular. We will start with an introduction to a mature language feature in C#. Then we will try to clone the partial classes feature in TypeScript. Lastly we will cover a special case: how to extend a class which are from another library/module.
C# partial classes
I used to be a C# programmer. And I have been missing a useful feature from C# since I started coding in TypeScript. This feature is named Partial Classes. Let me show you an example:
We see two class definitions, but they have an identical name Employee
. So they are actual for the same class. And each definition defines a method, DoWork
and GoToLunch
, respectively. The code above is equivalent to the following code snippet:
What is the point of C# partial classes?
Well, it allows you to define classes sparsely. You can even distribute a class definition in different files. It makes extending an existing class very simple: just declare the class as partial and extend it freely. It is especially useful when several people/teams work on the same class, each responsible for a different method. They can just write code in different files, and compiler will merge the partial code into a single class.
Partial class VS. subclass
You may extend an existing class by subclassing it:
public class Employee
{
public void DoWork()
{
}
}public class SubEmployee : Employee
{
public void GoToLunch()
{
}
}
But sometimes we don’t want it because it created a new class named SubEmployee
. If the Employee
class is already used everywhere and by everybody, it’s not easy to update them all to the new subclass.
Partial class feature allows us to “extend” an existing class without a subclass, thus without the need to update all the code to use the new subclass. That’s the main difference between partial class and subclass.
Partial classes for TypeScript
Unfortunately, TypeScript doesn’t support partial classes. And according to this thread, it will never support it. So how can we achieve the same effect in TypeScript? I created an demo project and I did lots of experiments, finally I found the following solution works like a charm:
I know you may be wondering: what is that interface for? Can we just add Employee.prototype.goToLunch = function(){}
directly? It is because we are writing TypeScript instead of JavaScript. We need to tell the compiler that Employee
has a method named goToLunch
, otherwise the code won’t compile at all.
It is as flexible as the C# partial classes, if not more flexible. We don’t even need to mark the original class as partial at all.
Extend a class from another module/library
What if we want to extend a class from another file? Let’s say the original file is employee-1.ts
and we want to extend it in employee-2.ts
. Code in employee-1.ts
:
export class Employee {
doWork: void {
}
}
Code in employee-2.ts
:
You can see the only change is: when you declare the interface, declare it in the same module as the original class.
And how about extending a class from another library? Let’s take the RingCentral Extensible library for example:
There isn’t too much difference from extending a class from another file at all.
Summary
OK, that concludes today’s article. In this article I shared my experience about extending a class freely in TypeScript. I hope you enjoy reading it. And don’t forget to apply this technique in your own projects!
Please let us know what you think by leaving your questions and comments below. To learn even more about other features we have make sure to visit our developer site and if you’re ever stuck make sure to go to our developer forum.
Want to stay up to date and in the know about new APIs and features? Join our Game Changer Program and earn great rewards for building your skills and learning more about RingCentral!