Tips & Tricks

Write Object-Oriented TypeScript: Polymorphism

This is part 4 of a 4 part article on how to program in TypeScript using object-oriented techniques. If you are just starting with TypeScript and WebStorm, see our blog post on Getting Started with TypeScript.

Implement polymorphism in TypeScript

When multiple classes inherit from a parent and override the same functionality, the result is polymorphism. Each of those child classes now implements a property or method, but they each may have their own way of performing that implementation.

For example, both business and personal checking accounts can inherit from a parent checking account. Calling a method to open the business checking account might require that the code checks for a higher initial deposit than when opening a personal checking account. A business account might require multiple owners, where a personal checking account can have one or more. Alternatively, one child class might override the parent’s members while another child doesn’t but just accepts the parent class’s implementation instead. This also demonstrates polymorphic behavior, since those behaviors are different between the siblings.

Polymorphism allows you to specify discrete logic that is customized for each specific child class. Let’s look at how this works with a CheckingAccount base class, and its two child classes: BusinessCheckingAccount and PersonalCheckingAccount.

class CheckingAccount {
  open(initialAmount: number) {
    // code to open account and save in database
  }
}

class BusinessCheckingAccount extends CheckingAccount {
  open(initialAmount: number) {
    if (initialAmount < 1000) {
      throw new Error("Business accounts must have an initial deposit of 1.000 Euros")
    }
    super.open(initialAmount);
  }
}

class PersonalCheckingAccount extends CheckingAccount {
  open(initialAmount: number) {
    if (initialAmount <= 0) {
      throw new Error("Personal accounts must have an initial deposit of more than zero Euros")
    }
    super.open(initialAmount);
  }
}

As the previous code sample shows, the two child classes have different business rules to implement when it comes to opening an account – mainly different opening balances. Because both children have a method to open the account but both children choose to do it differently means the behavior is polymorphic.

To achieve polymorphism, inherit from a base class, then override methods and write implementation code in them. In addition to overriding methods, you can overload methods to achieve polymorphism. Overloaded methods are methods that have different signatures (i.e., different data types or number of arguments) with the same name. However, in TypeScript, methods aren’t overloaded by simply modifying the types or number of arguments like in some other languages. To create an overload in TypeScript, you can either add optional arguments to a method, or overload function declarations in an interface and implement the interface.

In WebStorm, you can override methods by pressing Ctrl + O and then choosing the methods you want to override.

oop-override-methods

To implement an interface which contains the appropriate overloads, use Alt + Enter in WebStorm just like you would for a regular interface with no overloads.

implement an interface

As you can see in the above animation, WebStorm creates the overloaded methods including one that captures the any data type.

Summary

Polymorphism enables developers to model object-oriented systems to mimic real-world conditions in a more accurate way.

Part 1: Write Object-Oriented TypeScript: Inheritance
Part 2: Write Object-Oriented TypeScript: Abstraction
Part 3: Write Object-Oriented TypeScript: Encapsulation
[This article] Part 4: Write Object-Oriented TypeScript: Polymorphism

image description