Author Box


Discuss Your Project

About Us

We are Microsoft Gold partner with its presence across the United States and India. We are a dynamic and professional IT services provider that serves enterprises and startups, helping them meet the challenges of the global economy. We offer services in the area of CRM Consultation and implementation, Application development, Mobile application development, Web development & Offshore Development.

Interfaces in Typescript

Interfaces in Typescript: What are they and how to use them?

By Pooja Sharma / February 23, 2022

October 13, 2022
Interfaces in Typescript: What are they and how to use them?

What is Typescript?

Typescript is a “Typed” version of the JavaScript language whose goal is to introduce static typing to the language. TypeScript adds types to the JavaScript Code to speed up development by identifying problems before the JavaScript code is run. However, sometimes that could get messy and that’s the reason why it is also hated by some programmers.

Interfaces

Interfaces, in the simplest words, describe the structure of the object which means it describes how the object should look like. In TypeScript, we can work with “Interfaces”. In TypeScript, an interface just contains the definition of methods and properties, not their implementation. It is the functionality of the class that carries out the connection between the interface by providing the connection with all the parameters of the interface.

Creating An Interface

While creating a new interface, the interface keyword must be used. This keyword must be followed by the interface name. The curly brackets should contain the shape of an object, the properties, and the types. The properties and types are specified as “key: value” pairs while creating the Interface.

Below is an example of simple TypeScript interfaces. 

// Create an empty interface:
interface EmptyObject {}

// Create interface Person:
interface Person {
  name: string;
  age: number;
  hairColor: string;
  weight: number;
  height: number;
}

// Create interface Car:
interface Car {
  model: string;
  manufacturer: string;
  numberOfWheels: number;
  type: string;
}

// Create interface User:
interface User {
  name: string;
  pass: string;
  email: string;
}

Also, read: Top Web app development frameworks for 2022: get the most scalability at lower costs

Optional Properties in Interfaces

The declared interface may also have optional properties. To declare an optional property, the question mark (?) at the end of the property name is used during the declaration.

For example, if we take the Person Interface that we declared above-

// Create interface Person:
interface Person {
  name: string;
  weight? : number;
  age: number;
  hairColor? : string;
   height: number;
}

In the above example, the interface Person has two optional properties with the “?”. that is hairColor’ and weight, while the other three properties are the required properties.

Interface Annotation in Functional Components

Since the Person interface has been defined, now it can be used as a type, also can be annotated the function parameter with the interface name:

Let us again look at the Person Interface that we declared above:

interface PersonData {
  name: string;
 weight? : number;
  age: number;
  hairColor? : string; 
  height: number;
}

function getPersonDetail(person: PersonData) {
    return `${person.name} ${person.age} ${person.height}`;
}

let johnDoe = {
    name: 'John Doe',
    age: 25,
    height: 170,
};

console.log(getPersonDetail(johnDoe));

Output:

John Doe 25 170

In the above example, the TypeScript compiler checks the parameters or properties that are passed into the getPersonDetail() function.

If the argument has two properties whose types are numbers and one property whose type is a string, then the TypeScript compiler passes the check. Otherwise, it will throw an error.

Interface As Functions

Objects, including classes, are not the only things that can utilize interfaces. TypeScript interfaces may also be used to annotate functions. You can accomplish this by providing the interface with a call signature. This means you assign the interface to the function signature that contains the parameter list with types and returned types.

For example:

interface multiplyFunc {
// Specify only parameters and return type:
    (a: number, b: number, c: number): string;  
}
// Annotate the "multiply" function
// with "MultiplyFunc" interface:
const multiply: multiplyFunc = (a, b, c) => {
  return a * b * c
}

One thing about interfaces and functions. The name of parameters in an interface does not have to match the name of parameters in the actual function. You can also use a similar name for the interface parameter and for the function declaration. Using the order, TypeScript will appropriately relate arguments to their types. For example:

interface myFunction {
// Specify only parameters and return type:
    (a: string, b: Boolean, c: number): string;  
}
const myFunc: myFunction = (x, y, z) => {
  return `x is ${x}, y is ${y}, z is ${z}`
}
// TypeScript will correctly infer "a" to be number,
// "b" to be string and "c" to be boolean.

Also, read: Web App Development Cost: The 2021 Prices Breakdown

Interface As Class Types

A class creates a blueprint for how an object should appear and behave and then implements that blueprint by defining methods and initializing class attributes. As a result, when we create an instance of the class, we obtain an object with specified attributes and actionable functions.

Interface with JavaScript classes is also possible with TypeScript. The implementation of classes, on the other hand, is slightly different. The interface is still specified after the name, in this case, the class name. You do not, however, use colons between the class name and the interface.

Instead, you simply update the colons with the implements keyword. This instructs TypeScript to utilize an interface that comes after this keyword in each class.

// Create interface Person:
interface Person {
  // Define some class properties
  // of type string and number:  
  name: string;
  weight? : number; 
  age: number;
  height: number;
  hairColor? : string;
}
  // Define class method that returns a string:
  sayHello: () => string;
}

// Annotate the class "Myself" with the "Person" interface:
class Myself implements Person { 
   name: string;
   weight? : number;
   age: number;
   height: number;
  hairColor? : string;
}

  // Create constructor and assign existing properties:
  constructor(name: string, age: number, weight? : number,  hairColor? : string,    height: number) {
    this.name = name
    this.weight = weight
    this.hairColor = hairColor
    this.age = age
    this.height = height 
  }

  // Define required class method:
  sayHello() {
    return `Hello, my name is ${this.name}.`
  }
}

ReadOnly Properties

You may wish to restrict some attributes from being updated while creating an object. TypeScript interfaces can also be used to indicate this purpose. The readonly keyword is used before the property name to accomplish this. This instructs TypeScript that the next property is a readonly property. You can only set the value for the readonly property during initialization if you use the interface to annotate an object. The TypeScript compiler will generate an error if you try to alter the property value later.

interface CarProperties {
    readonly length: number;
    readonly width: number;
    readonly wheelbase: number;
    readonly seatingCapacity: number;
}

Readonly properties cannot be altered after they have been initialized. The attributes length, breadth, wheelbase, and seating capacity can never be changed after they have been initialized with a set value.

Also, read: Top Web App Development Mistakes to avoid in 2022

Extending Interfaces

The Extending Interfaces can extend any other Interface to import the properties of that Interface. This helps in creating small and reusable components. While extending interfaces with multiple interfaces we have to separate them with commas. We use extended keywords between the first interface, and the second Interface, to extend their properties.

// Create "Person" interface:
interface Person {
  name: string;
}

// The "Male" interface created extends the "Person" interface:
interface Male extends Person {
  gender: 'Male';
}
// In terms of Interface, this means:
// interface Male {
//   name: string;
//   gender: 'Male';
// }

// Now the "Female" interface is created to extend the "Person" interface:
interface Female extends Person {
  gender: 'Female';
}
// This Interface mean:
// interface Female {
//   name: string;
//   gender: 'Female';
// }

// Now the "Boy" interface is created to extend both “Male” and "Person" interfaces:
interface Boy extends Person, Male {
  age: number;
}
// which usually mean:
// interface Boy {
//   age: number;
//   gender: 'Male';
//   name: string;
// }

// Now the "Girl" interface is created to extend both "Female" and "Person" interfaces:
interface Girl extends Person, Female {
  age: number;
}
// which converts to:
// interface Girl {
//   age: number; 
//   gender: 'Female';
//   name: string;
// }

const akshay: Person = {
  name: 'Akshay'
}

const suraj: Male = {
  name: Suraj,
  gender: 'Male'
}

const sarah: Female = {
  name: 'Sarah',
  gender: 'Female'
}

const ahmad: Boy = {
  name: ‘Ahmad’,
  gender: 'Male',
  age: 26
}

const aayat: Girl = {
  name: 'Aayat',
  gender: 'Female',
  age: 18
}

Indexable types

Indexed objects are the objects whose properties can be accessed using an index signature such as obj[`property']. This is the standard way to access array elements, but you can also do it for objects. For example, we can define a type selectCar as:

Interface selectCar{
[index: number]: string
}
let cars: selectCar = ['Hatchback', 'Sedan', 'Land Rover', 'Premium']
console.log('Element at position 1', cars[1])       // 'Sedan'

Let us look at another example:

The interface with the name PersonObject defines the shape of an object with keys used as a string type and the values of the object can be any data type. Here, the key property is only used as a placeholder because it is enclosed in square brackets.

// declare indexable interface types
Interface PersonObject {
	[key: string]: any;
}

// declare few objects of type ‘PersonObject’
Let akshay: PersonObject = { name: “Akshay Bisht”, age: 27 };
Let ahmad: PersonObject = { name: “Ahmed”, 1: 26 };

// print values
console.log(‘akshay == > ’, akshay);	
--> akshay = = > { name : ‘Akshay Bisht’, age: 27 }
console.log(‘ahmed == > ’, ahmed);
--> ahmed = = > { name : ‘Ahmed’, 1: 26 }

Also, read: How to call web API with useEffect hook in React TypeScript?

Generic Interfaces

TypeScript also allows you to create so-called "generic interfaces". These interfaces allow you to specify the type of property based on one or more parameters that you make available to the interface when you use it. TypeScript generics are used when you need to create generic components that work with multiple data types.

For example, we do not want to limit a function to accept only numbers as input parameters. It needs to be extended based on use-cases to accept distinct types. The specification of the generic Interfaces is done by using angle brackets (<>) as shown in the example given below.

let cars: CarSpecification<CarModels> = Stack
let carModels = [
    {
        company: 'Tata',
        modelid: 1,
        length: 112,
    },
]
let newCar = new cars(carModels)
console.log(newCar)        --- >   // prints the value of `carModels`

Using Generics in Asynchronous tasks: 
// Create interface for PersonObject:
interface PersonObject {
  name: string;
  email: string;
}

// Create a generic interface:
interface ApiData<T> {
  payload: T[];
  code: number;	
  date: Date;
}

// Create function to fetch API
async function fetchAPI() {
  // Use ApiData "interface" and pass the "UserData" interface as argument (for T argument):
  const data: ApiData<UserData> = await fetch('/URL_endpoints')

  // The "ApiData<UserData>" converts to:
  // interface ApiDatae<T> {
  //   code: number;
  //   date: Date;
  //   payload: UserData[];
  //  }
}

Why Use Interfaces?

One specific example: Interfaces are a productive way of specifying the types that other codes must meet. The Interfaces allows the JavaScript to know about the typed version of the objects that are to be used in the library of code.

Suppose we are writing some sort of library code, which means we have to write that code as it is also valid for objects, the objects that have a certain set of properties. The most effective way is to specify those properties in an interface (no implementation, just a description) and use the references to the objects to implement the Interface in our library code.

What it does is, allow any random person to create a class that implements that interface, and to use an object of the created class and implement it, our code needs to work with it.

Conclusion

Interfaces are the most effective way of defining types in TypeScript. Let us look at a small summary of what we have learned in this tutorial:

  • Interfaces define the specifications of entities, the types of the objects, and implementation by using functions or classes. We can specify optional properties on an interface using ‘?’ and use the ‘readonly’ keyword to the properties that cannot be changed (readonly properties) in the property name.
  • The TypeScript compiler additionally checks for abundance properties on an article and gives a mistake assuming an item contains a property that is already been defined in the Interface.
  • We learned how to define Indexable properties, optional parameters, extending interfaces using interfaces.
  • Classes and Functions can also be implemented with an interface. The interface contains the definition just for the instance variables of a class.
  • Interfaces can also be used to import the properties of other Interfaces, we do it by using the extends keyword.
  • We can also build the reusable components that we can use repeatedly in our library of code by using the generics with the Interfaces.
[sc name="Web Development"] [add_newsletter] [add_related_page_diff_contents blog_cat = "web-application"]

What is Typescript?

Typescript is a “Typed” version of the JavaScript language whose goal is to introduce static typing to the language. TypeScript adds types to the JavaScript Code to speed up development by identifying problems before the JavaScript code is run. However, sometimes that could get messy and that’s the reason why it is also hated by some programmers.

Interfaces

Interfaces, in the simplest words, describe the structure of the object which means it describes how the object should look like. In TypeScript, we can work with “Interfaces”. In TypeScript, an interface just contains the definition of methods and properties, not their implementation. It is the functionality of the class that carries out the connection between the interface by providing the connection with all the parameters of the interface.

Creating An Interface

While creating a new interface, the interface keyword must be used. This keyword must be followed by the interface name. The curly brackets should contain the shape of an object, the properties, and the types. The properties and types are specified as “key: value” pairs while creating the Interface.

Below is an example of simple TypeScript interfaces. 

// Create an empty interface:
interface EmptyObject {}

// Create interface Person:
interface Person {
  name: string;
  age: number;
  hairColor: string;
  weight: number;
  height: number;
}

// Create interface Car:
interface Car {
  model: string;
  manufacturer: string;
  numberOfWheels: number;
  type: string;
}

// Create interface User:
interface User {
  name: string;
  pass: string;
  email: string;
}

Also, read: Top Web app development frameworks for 2022: get the most scalability at lower costs

Optional Properties in Interfaces

The declared interface may also have optional properties. To declare an optional property, the question mark (?) at the end of the property name is used during the declaration.

For example, if we take the Person Interface that we declared above-

// Create interface Person:
interface Person {
  name: string;
  weight? : number;
  age: number;
  hairColor? : string;
   height: number;
}

In the above example, the interface Person has two optional properties with the “?”. that is hairColor’ and weight, while the other three properties are the required properties.

Interface Annotation in Functional Components

Since the Person interface has been defined, now it can be used as a type, also can be annotated the function parameter with the interface name:

Let us again look at the Person Interface that we declared above:

interface PersonData {
  name: string;
 weight? : number;
  age: number;
  hairColor? : string; 
  height: number;
}

function getPersonDetail(person: PersonData) {
    return `${person.name} ${person.age} ${person.height}`;
}

let johnDoe = {
    name: 'John Doe',
    age: 25,
    height: 170,
};

console.log(getPersonDetail(johnDoe));

Output:

John Doe 25 170

In the above example, the TypeScript compiler checks the parameters or properties that are passed into the getPersonDetail() function.

If the argument has two properties whose types are numbers and one property whose type is a string, then the TypeScript compiler passes the check. Otherwise, it will throw an error.

Interface As Functions

Objects, including classes, are not the only things that can utilize interfaces. TypeScript interfaces may also be used to annotate functions. You can accomplish this by providing the interface with a call signature. This means you assign the interface to the function signature that contains the parameter list with types and returned types.

For example:

interface multiplyFunc {
// Specify only parameters and return type:
    (a: number, b: number, c: number): string;  
}
// Annotate the "multiply" function
// with "MultiplyFunc" interface:
const multiply: multiplyFunc = (a, b, c) => {
  return a * b * c
}

One thing about interfaces and functions. The name of parameters in an interface does not have to match the name of parameters in the actual function. You can also use a similar name for the interface parameter and for the function declaration. Using the order, TypeScript will appropriately relate arguments to their types. For example:

interface myFunction {
// Specify only parameters and return type:
    (a: string, b: Boolean, c: number): string;  
}
const myFunc: myFunction = (x, y, z) => {
  return `x is ${x}, y is ${y}, z is ${z}`
}
// TypeScript will correctly infer "a" to be number,
// "b" to be string and "c" to be boolean.

Also, read: Web App Development Cost: The 2021 Prices Breakdown

Interface As Class Types

A class creates a blueprint for how an object should appear and behave and then implements that blueprint by defining methods and initializing class attributes. As a result, when we create an instance of the class, we obtain an object with specified attributes and actionable functions.

Interface with JavaScript classes is also possible with TypeScript. The implementation of classes, on the other hand, is slightly different. The interface is still specified after the name, in this case, the class name. You do not, however, use colons between the class name and the interface.

Instead, you simply update the colons with the implements keyword. This instructs TypeScript to utilize an interface that comes after this keyword in each class.

// Create interface Person:
interface Person {
  // Define some class properties
  // of type string and number:  
  name: string;
  weight? : number; 
  age: number;
  height: number;
  hairColor? : string;
}
  // Define class method that returns a string:
  sayHello: () => string;
}

// Annotate the class "Myself" with the "Person" interface:
class Myself implements Person { 
   name: string;
   weight? : number;
   age: number;
   height: number;
  hairColor? : string;
}

  // Create constructor and assign existing properties:
  constructor(name: string, age: number, weight? : number,  hairColor? : string,    height: number) {
    this.name = name
    this.weight = weight
    this.hairColor = hairColor
    this.age = age
    this.height = height 
  }

  // Define required class method:
  sayHello() {
    return `Hello, my name is ${this.name}.`
  }
}

ReadOnly Properties

You may wish to restrict some attributes from being updated while creating an object. TypeScript interfaces can also be used to indicate this purpose. The readonly keyword is used before the property name to accomplish this. This instructs TypeScript that the next property is a readonly property. You can only set the value for the readonly property during initialization if you use the interface to annotate an object. The TypeScript compiler will generate an error if you try to alter the property value later.

interface CarProperties {
    readonly length: number;
    readonly width: number;
    readonly wheelbase: number;
    readonly seatingCapacity: number;
}

Readonly properties cannot be altered after they have been initialized. The attributes length, breadth, wheelbase, and seating capacity can never be changed after they have been initialized with a set value.

Also, read: Top Web App Development Mistakes to avoid in 2022

Extending Interfaces

The Extending Interfaces can extend any other Interface to import the properties of that Interface. This helps in creating small and reusable components. While extending interfaces with multiple interfaces we have to separate them with commas. We use extended keywords between the first interface, and the second Interface, to extend their properties.

// Create "Person" interface:
interface Person {
  name: string;
}

// The "Male" interface created extends the "Person" interface:
interface Male extends Person {
  gender: 'Male';
}
// In terms of Interface, this means:
// interface Male {
//   name: string;
//   gender: 'Male';
// }

// Now the "Female" interface is created to extend the "Person" interface:
interface Female extends Person {
  gender: 'Female';
}
// This Interface mean:
// interface Female {
//   name: string;
//   gender: 'Female';
// }

// Now the "Boy" interface is created to extend both “Male” and "Person" interfaces:
interface Boy extends Person, Male {
  age: number;
}
// which usually mean:
// interface Boy {
//   age: number;
//   gender: 'Male';
//   name: string;
// }

// Now the "Girl" interface is created to extend both "Female" and "Person" interfaces:
interface Girl extends Person, Female {
  age: number;
}
// which converts to:
// interface Girl {
//   age: number; 
//   gender: 'Female';
//   name: string;
// }

const akshay: Person = {
  name: 'Akshay'
}

const suraj: Male = {
  name: Suraj,
  gender: 'Male'
}

const sarah: Female = {
  name: 'Sarah',
  gender: 'Female'
}

const ahmad: Boy = {
  name: ‘Ahmad’,
  gender: 'Male',
  age: 26
}

const aayat: Girl = {
  name: 'Aayat',
  gender: 'Female',
  age: 18
}

Indexable types

Indexed objects are the objects whose properties can be accessed using an index signature such as obj[`property‘]. This is the standard way to access array elements, but you can also do it for objects. For example, we can define a type selectCar as:

Interface selectCar{
[index: number]: string
}
let cars: selectCar = ['Hatchback', 'Sedan', 'Land Rover', 'Premium']
console.log('Element at position 1', cars[1])       // 'Sedan'

Let us look at another example:

The interface with the name PersonObject defines the shape of an object with keys used as a string type and the values of the object can be any data type. Here, the key property is only used as a placeholder because it is enclosed in square brackets.

// declare indexable interface types
Interface PersonObject {
	[key: string]: any;
}

// declare few objects of type ‘PersonObject’
Let akshay: PersonObject = { name: “Akshay Bisht”, age: 27 };
Let ahmad: PersonObject = { name: “Ahmed”, 1: 26 };

// print values
console.log(‘akshay == > ’, akshay);	
--> akshay = = > { name : ‘Akshay Bisht’, age: 27 }
console.log(‘ahmed == > ’, ahmed);
--> ahmed = = > { name : ‘Ahmed’, 1: 26 }

Also, read: How to call web API with useEffect hook in React TypeScript?

Generic Interfaces

TypeScript also allows you to create so-called “generic interfaces“. These interfaces allow you to specify the type of property based on one or more parameters that you make available to the interface when you use it. TypeScript generics are used when you need to create generic components that work with multiple data types.

For example, we do not want to limit a function to accept only numbers as input parameters. It needs to be extended based on use-cases to accept distinct types. The specification of the generic Interfaces is done by using angle brackets (<>) as shown in the example given below.

let cars: CarSpecification<CarModels> = Stack
let carModels = [
    {
        company: 'Tata',
        modelid: 1,
        length: 112,
    },
]
let newCar = new cars(carModels)
console.log(newCar)        --- >   // prints the value of `carModels`

Using Generics in Asynchronous tasks: 
// Create interface for PersonObject:
interface PersonObject {
  name: string;
  email: string;
}

// Create a generic interface:
interface ApiData<T> {
  payload: T[];
  code: number;	
  date: Date;
}

// Create function to fetch API
async function fetchAPI() {
  // Use ApiData "interface" and pass the "UserData" interface as argument (for T argument):
  const data: ApiData<UserData> = await fetch('/URL_endpoints')

  // The "ApiData<UserData>" converts to:
  // interface ApiDatae<T> {
  //   code: number;
  //   date: Date;
  //   payload: UserData[];
  //  }
}

Why Use Interfaces?

One specific example: Interfaces are a productive way of specifying the types that other codes must meet. The Interfaces allows the JavaScript to know about the typed version of the objects that are to be used in the library of code.

Suppose we are writing some sort of library code, which means we have to write that code as it is also valid for objects, the objects that have a certain set of properties. The most effective way is to specify those properties in an interface (no implementation, just a description) and use the references to the objects to implement the Interface in our library code.

What it does is, allow any random person to create a class that implements that interface, and to use an object of the created class and implement it, our code needs to work with it.

Conclusion

Interfaces are the most effective way of defining types in TypeScript. Let us look at a small summary of what we have learned in this tutorial:

  • Interfaces define the specifications of entities, the types of the objects, and implementation by using functions or classes. We can specify optional properties on an interface using ‘?’ and use the ‘readonly’ keyword to the properties that cannot be changed (readonly properties) in the property name.
  • The TypeScript compiler additionally checks for abundance properties on an article and gives a mistake assuming an item contains a property that is already been defined in the Interface.
  • We learned how to define Indexable properties, optional parameters, extending interfaces using interfaces.
  • Classes and Functions can also be implemented with an interface. The interface contains the definition just for the instance variables of a class.
  • Interfaces can also be used to import the properties of other Interfaces, we do it by using the extends keyword.
  • We can also build the reusable components that we can use repeatedly in our library of code by using the generics with the Interfaces.

Web Development Services

Are you looking for a reliable web development company? Our highly skilled web developers enables us to deliver result oriented web development services. Contact our team to understand, how we can help you in achieving your business goals.



guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x