Abstract Classes in Typescript
Tags: typescript, javascript, codenewbie
Published: 2020-04-27 14:43:49

In Typescript the classes can inherit from another class to share methods and properties between classes also Typescript support abstract class, let me show why and when to use it.

For example, we have a base class Subscription and create the new subclass FrenchSubscription with his own sign method implementation.

```javascript
class Subscription {
	url: string = "";
	constructor(public name: string) {
		this.name = name;
	}
	sign(): string {
		return "Signup!!";
	}
}

class FrenchSubscription extends  Subscription {
	url: string = "http://www.typescript.fr";
	sign(): string {
		return `Bonjour ${this.name} please go to ${this.url}`;
	}
}

```
We create a new SubscriptionManager class to process a list of subscriptions and use the sign method to show a message.

The SubscriptionManager will support future subscription's child class, like EnglishSubscription class.

The SubscriptionManager has a process method to iterate over every subscription and call the sign method to show the message.

```javascript
class SubscriptionManager {
	static subscriptions: Array<Subscription> = [];
	static process() {
		this.subscriptions.forEach((p) => {
			let message =  p.sign();
			console.log(message)
		})
	}
}

```
The SubscriptionManager is ready to works, then add a Subscription instance to subscriptions and process it.

```javascript
let france = new FrenchSubscription('Paris');
SubscriptionManager.subscriptions.push(france);

SubscriptionManager.process();
```
```javascript
[nodemon] starting `node Student.js`
Bonjour Paris please go to http://www.typescript.fr
```
Nodemon runs the app, and perfect!! Everything works! Go to live, because my code works, but has some weaknesses.

A new developer comes to the company and needs to create a new class for English, it will inherit from the Subscription base class.
He creates EnglishSubscription and the sign method because everything looks fine IDE, and the compiler won't complain about it. Commit his changes.

```javascript
class EnglishSubscription extends Subscription {
	url: string = "http://www.typescript.us";
	sign() {
		return false;
	}
}
``` 
The service start to use the EnglishSubscription class, and it is a Subscription object will contain the sign method.

```javascript
let france = new FrenchSubscription('Paris');
let ny = new EnglishSubscription('New York');

SubscriptionManager.subscriptions.push(france);
SubscriptionManager.subscriptions.push(ny)

SubscriptionManager.process();
```
CRASHH!! The result is not as we expect!!!

```bash
Bonjour Paris please go to http://www.typescript.fr
false
```
We had a bug and error, the method exists but doesn't fit with the initial contract and the developer doesn't know how what is the contract with the SubscriptionManager.
 
Sometimes we need to be sure the developer fits with the goal of the base class and be sure every child class based on it implements all members with field, methods, and signature.

Then, it is time to use the **abstract class**, using the abstract keyword before the method and class name them our normal class becomes to be an **abstract class** and every child class must implement the method with the expected signature.
 
 _Tip: The abstract methods don’t have an implementation._

```javascript
abstract class Subscription {
	url: string = "";
	constructor(public name: string) {
		this.name = name;
	}
	abstract sign(): string { }
}
```
The child classes from Subscription must implement the sign method with the signature, if not the IDE and compiler will raise an error.

```javascript
 Property 'sign' in type 'EnglishSubscription' is not assignable to the same property in base type 'Subscription'. 
  Type '() => boolean' is not assignable to type '() => string'.     Type 'boolean' is not assignable to type 'string'.
```

Using abstract the developers understand what is the goal of the base class Subscription, and his methods also we are sure for each child class 
implements the methods for the proposal with an expected result but different behavior, and our code is safe and flexible.

Hopefully, that will give you a bit of help with abstract classes in Typescript. If you enjoyed this post, share it.

Photo by <a href="https://unsplash.com/@karsten116?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Karsten Winegeart</a> on <a href="https://unsplash.com/s/photos/dog?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>