Looking at Abstract Classes and Methods in TypeScript

Paul Galvin
3 min readOct 19, 2015

--

[Hi there — I recently published a free book on TypeScript, Yet Another TypeScript Book, that you can read here: https://www.gitbook.com/book/pagalvin/yet-another-typescript-book/details.]

I am probably far too happy about the fact that TypeScript now supports abstract classes. As we say back in my homeland where people pronounce things propahly, abstract classes are “wicked awesome.” Many, many tried and true software development patterns leverage them.

In this article, I am going to show an abstract class that supplements what I already wrote about the Observer pattern here, “Implement the Observer Pattern in TypeScript.” You can find all related code up at Github here: https://github.com/pagalvin/Patterns.

Setup

To show this in action, I took the Observer pattern code and started by refactoring the ScoreDataServer class. For easy reference, this is the ScoreDataServer class:

https://github.com/pagalvin/Patterns/blob/master/Observer/BusinessObjects/ScoreDataServer.ts#L3

ScoreDataServer is going to publish scores to clients who express their interest via the RegisterObserver() method. That method is defined in the BasePublisher class:

https://github.com/pagalvin/Patterns/blob/master/Observer/BusinessObjects/Publisher.ts#L3

The Problem

BasePublisher fully implements the Register and Remove methods. When I first wrote this class, I didn’t have the latest version of TypeScript available to me, so what I did was toss out an alert if the user failed to provide their own override version of NotifyObservers when they subclassed BasePublisher. This is obviously sub-optimal. TypeScript’s abstract classes and methods solve this problem.

The Solution

I created a new version of BasePublisher and called it AbstractEventPublisher. This is what it looks like with the new syntax highlighted:

https://github.com/pagalvin/Patterns/blob/master/Observer/BusinessObjects/AbstractPublisher.ts#L4

This abstract class does two things:

  1. Creates a new abstract class called AbstractPublisher. This abstract class implements the IObservable interface. You can see how they play nicely together.
  2. It provides an abstract defintion for NotifyObservers. Since it’s abstract, any subclass must implement it.
  3. It provides concrete implementions of RegisterObserver() and NotifyObservers().

The solution is now significantly better than it was before. The transpilation will now fail if you don’t implement NotifyObservers() in the subclass and Visual Studio (and all good IDEs) will tell you why. You don’t need to rely upon some kind of naming convention to help remind you when you’re writing your publisher type objects or throw up an alert() to catch it at run-time. At the same time, your subclasses get all that register/remove logic for free.

Miscellaneous Fun Fact

One thing to note with abstract classes is that unlike an interface, abstract classes may have to be referenced in your app’s index.html file (or equivalent). In this case, the AbstractPublisher provides a concrete implementation for Register/Remove. The transpiler emits that actual code. Mine looks like this:

As a result, you need to reference the abstract class in your index.html.

On the other hand, if you abstract class doesn’t implement anything, it acts like an interface as far as the transpiler is concerned. Nothing is generated and it’s only used at compile time (and the IDE).

Happy coding!

</end>

--

--

Paul Galvin

Author and Practice Director @ Neudesic/IBM. Father, Not-Great-But-Always-Trying Zen Buddhist. “Yet Another TypeScript Book” (https://amzn.to/2ABntAX).