Categories
TypeScript

Using TypeScript — Interfaces and Abstract Classes

Spread the love

TypeScript is a natural extension of JavaScript that’s used in many projects in place of JavaScript. However, not everyone knows how it actually works.

In this article, we’ll look at how to work with interfaces and abstract classes in TypeScript.

Extending Interfaces

Like classes, interfaces can be extended. We use the same approach as extending classes.

For instance, we can write:

interface Person {
  name: string;
  getName(): string;
}

interface Owner extends Person {
  item: string;
  getItemDetails(): string;
}

We use the extends keyword like we do with classes.

It has the same meaning. The members from the parent interfaces are inherited by the child interface.

For instance, we can write:

interface Person {
  name: string;
  getName(): string;
}

interface Owner extends Person {
  item: string;
  getItemDetails(): string;
}

class ThingOwner implements Owner {
  constructor(public name: string, public item: string) {}

  getName() {
    return this.name;
  }

  getItemDetails() {
    return this.item;
  }
}

We have all the members from each interface implemented.

The implements keyword means that we must implement everything in the child interface including inherited members.

Interfaces and Shape Types

Interfaces and shape types are different, even though they might look similar.

Interfaces can be used with the implements keyword to make a class implement everything in the interface.

Shape types can only be assigned directly to a variable. However, interfaces can conform to shape types.

For instance, we can use the extends keyword with a shape type:

type Person = {
  name: string;
  getName(): string;
};

interface Owner extends Person {
  item: string;
  getItemDetails(): string;
}

class ThingOwner implements Owner {
  constructor(public name: string, public item: string) {}

  getName() {
    return this.name;
  }

  getItemDetails() {
    return this.item;
  }
}

The extends keyword indicates that our interface includes all the members of the shape type.

Optional Interface Properties and Methods

Interface properties and methods can be optional. The ? indicates that it’s an optional member.

For instance, we can write:

type Person = {
  name: string;
  getName?(): string;
};

interface Owner extends Person {
  item: string;
  getItemDetails?(): string;
}

class ThingOwner implements Owner {
  constructor(public name: string, public item: string) {}

  getName() {
    return this.name;
  }

  getItemDetails() {
    return this.item;
  }
}

We made getName and getItemDetails optional with the ? symbol.

Optional interface features can be defined through interface types without causing compiler errors. But we must be sure that we don’t receive undefined values since they may not exist in the returned object.

Abstract Interface Implementation

We can have abstract interfaces in our code.

We can use the abstract keyword with the members of the abstract class so that the implementation is in the concrete classes rather than the abstract class itself.

For instance, we can write:

interface Person {
  name: string;
  getName(): string;
}

abstract class Owner implements Person {
  name: string;
  abstract getName(): string;
}

class ThingOwner implements Owner {
  constructor(public name: string, public item: string) {}

  getName() {
    return this.name;
  }
}

We have an Owner abstract class that implements the Person interface.

The ThingOwner class implements the abstract class with a concrete implementation of getName .

Dynamically Creating Properties

JavaScript allows new properties to created on an object by assigning value to an unused property name.

With TypeScript, we can allow dynamic properties on our interfaces by providing index signatures.

For instance, we can write:

interface Person {
  name: string;
  [prop: string]: any;
}

to add an index signature to the Person interface.

The line:

[prop: string]: any;

is the index signature, and it allows us to add any string property to anything that has Person as a type.

We can assign any value to the dynamic property.

Conclusion

We can extend interfaces as we do with subclasses.

Also, we can implement shape types with interfaces.

Interfaces can enforce the structure of classes and objects.

Also, abstract class can enforce the structure of objects.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *