Understanding the use of interfaces in TypeScript

Publication date: 01 - 2 - 2024

Let's begin by defining what's a TypeScript interface

Interfaces are a custom data type that we can use in the development of our pages or applications. In them we can define the properties we need, as opposed to a pre-established object or a JSON file.

As we know, TypeScript is characterized by having a data typing that allows us a better control the information that we are going to handle during the development process. For example, if in a function that performs a mathematical operation we expect it to return a number value, with an algorithm, request or more complex operation we can assign that the type of data returned is one that we ourselves have established at our convenience.

How to declare an interface and where to store it?

This "mold" that will store the data is advisable to save and declare it in a separate file for later use. If you are going to develop an application with Angular, for example, you will need to create an exclusive file for the interfaces and from that file export the interfaces you need and import it into the component where you require it. This way you centralize this resource so that it can be used in any part of the application. The same applies if you are not developing with a framework, having an exclusive storage folder is a common development practice (It also happens with components, providers or services but these are topics that are separate from this post 😝).

Now, assuming you created your interfaces file in a path like /app/src/interfaces-app/interfaces.ts let's see how to declare them.

export interface YourInterfaceName{
property1:dataType;
property2:string;
property3:number;
}

In this illustrative pseudo code example we see the following features 🧐:

  1. The export declaration is used to be able to take this interface elsewhere in the app.

  2. The reserved word interface is used to declare that it is a custom data type.

  3. The name you are going to assign to your interface is declared.

Regarding properties. ☝🏻

Like any variable in TypeScript you can assign what data type you want it to be according to your convenience or need. As a tip, you can assign another interface in the properties.

How to use the interface already created?

You must go to the component, provider, page or module where you are going to use your interface and once there import it. This step, although silly, is relevant because sometimes we pull our hair out over something that is not working and it is because not having done the corresponding export/import. 😅 It is always good to check this and not to rely on auto-completions.

import {YourInterfaceName} from "/wherever-you-have-created-the-file";

The use you want to give it will depend on your development, either because you made an API yourself, customized the response and want to render it or you want to maintain a standard in the presentation of your data. Any use you need is valid.

So far we have seen the basic creation and use of a TypeScript interface although you can play with the property information.

Default values, locked values and optional values in a typescript interface

Default values in an interface are data that you cannot change or reassign as if it were an object literal. Locked values, unlike a default value, can only be assigned once if the type of data to be contained in that property was specified in the interface (we will see it below with an example). Optional values are those that are not mandatory to use; a detail of the interfaces is that if properties are declared without being optional it is because all properties must be used.

interface YourInterfaceName{
defaultValue:"This data is immovable";
readonly blockedProperty:string;
opcionalProperty?:number;
}

What changes when properties are declared in this way? 🤔

  1. The default values are going to stay that way during the flow of the application unless you change it in its root directory.

  2. Locked properties can be assigned a value according to their data type and these are going to be immutable. For a property to be locked it is preceded by the reserved word readonly .

  3. The way to declare an optional property is placing a closing question mark (?) at the end of the name of the property, this makes that at the moment of using the interface it is not necessary to use this data.

Applying inheritance with TypeScript interfaces

Interfaces are treated as objects or classes and as such their characteristics can be applied. Interfaces can be created that inherit properties from another interface.

For this example I will use a parallel to the Kimetsu no Yaiba series with the protagonist Tanjiro Kamado.

Preamble:

Kimetsu no Yaiba is about a series where there are two factions fighting each other, the demons and the demon hunters; the latter possess abilities based on "elemental breaths" that they combine with Japanese sword techniques. The protagonist is a hunter and we will take the characteristics of the hunters to create Tanjiro.

//Creating the interface

interface DemonSlayer{
name:string;
breath:string;
rank:string;
swordColor:string;
demonsKilled?:number;
}

//Creating another interface inheriting the features of DemonSlayer

interface MarkedDemonSlayer extends DemonSlayer{
skill1:string;
skill2:string;
}

//Creating the prota xD

const newDemonSlayer:MarkedDemonSlayer = {
name:"Tanjiro Kamado";
breath:"Water breath";
rank:"Kanoe";
swordColor:"Black";
skill1:"Solar breath";
skill2:"A hard head but this data is for the example xD";
}