Similar to Type Aliases, TypeScript’s Interfaces provide us a medium to avoid code duplication across our TypeScript codebases.

If we were to look at the alternative way of defining types, we would find ourselves defining and redefining types inline each time we want to benefit from TypeScript’s strong static typing system.

What Is an Interface?

Interfaces fill the role of bringing a name to the types we are used to defining and are a compelling way of expressing contracts within our code, as well as defining contracts with code outside our projects (E.g. NPM Packages).

The programming concept behind interfaces and contracts is brought under the term of Design by contract, which is a Programming Paradigm.

Interfaces may store, but are not limited to:

You can read more about the everyday types that are available to us on the TypeScript Official Docs.

Interface Syntax

The syntax for using Interfaces in TypeScript is similar to that of anonymous object type declarations.

interface MyNumberInterface {
  myNumber: number;
};

interface MyStringInterface {
  myString: string;
};

interface MyArrayInterface {
  arr: Array<MyNumberInterface | MyStringInterface>;
}

interface MyObjectInterface {
  myString: string;
  myNumber: number;
};

interface Person {
  firstName: string;
  lastName: string;
  email: string;
};

interface Address {
  addressLineOne: string;
  addressLineTwo?: string; // Optional Property
  city: string;
  stateOrProvince: string;
  zipOrPostalCode: string;
  country: string;
}

As you may notice, we can also define interfaces as part of other interfaces, thus making our lives much easier when dealing with nested objects or complex data structures.

As you would expect, we can also export them, thus needing to define them once in the root of our project/application and use them whenever and wherever needed.

Furthermore, we can use existing interface definitions to extend other interface definitions, thus making it easier to work with interfaces as a whole and with classes and abstract classes in TypeScript.

Extending Interfaces

Similarly to other static strongly typed languages, TypeScript provides us with the possibility to extend an interface using the following syntax:

interface Person {
  firstName: string;
  lastName: string;
  email: string;
};

interface Address {
  addressLineOne: string;
  addressLineTwo?: string; // Optional Property
  city: string;
  stateOrProvince: string;
  zipOrPostalCode: string;
  country: string;
}

interface PersonWithAddress extends Person, Address {};

const person: Person = {
  firstName: 'Mike',
  lastName: 'Smith',
  email: 'mike.smith@mail.com',
};

const address: Address = {
  addressLineOne: 'Some address',
  city: 'New York',
  zipOrPostalCode: 'A zip code',
  stateOrProvince: 'NY',
  country: 'United States',
};

const personWithAddress: PersonWithAddress = {
  ...person,
  ...address,
};

We can extend as many interfaces as we wish, thus, creating a union where in our case, the PersonWithAddress interface inherits the fields of both the Person interface, but those of the Address interface.

Read-only Fields

Apart from all of the features we’ve gone through above, we may also mark specific fields of an interface as being read-only, meaning that an object implementing said interface will not be able to have its read-only field reassigned:

interface ObjectWithReadonlyProperties {
  readonly [property: string]: any;
};

const readonlyObject: ObjectWithReadonlyProperties = {
  myProperty: 'Some value',
  myOtherProperty: 'Some other value',
};

readonlyObject.myProperty = 12; // Error: "Index signature in type 'ObjectWithReadonlyProperties' only permits reading."

As outlined in the helper comment, if I were to try to reassign a read-only property I would be greeted by the following message:

Read-only field reassignment rrror: "Index signature in type 'ObjectWithReadonlyProperties' only permits reading."
“Index signature in type ‘ObjectWithReadonlyProperties’ only permits reading.”

Summary

Although a relatively short read, I hope you’ve enjoyed it and got a better understanding of what Interfaces are, what they are used for, the benefits they bring to the table, and how we would use them in our TypeScript applications.

Also to note, interfaces are especially useful when working with TypeScript inside React; you can check out an article highlighting the creation of a new React project with TypeScript, or even the addition of TypeScript to an already existing React project here.

Feel free to let me know whether I’ve left something important out or if you have any feedback on this article by leaving a comment using the section below.

Cheers!

👋 Hey, I'm Vlad Mihet
I'm Vlad Mihet, a blogger & Full-Stack Engineer who loves teaching others and helping small businesses develop and improve their technical solutions & digital presence.

💬 Leave a comment

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

We will never share your email with anyone else.

Comments