Interface in TypeScript
Overview
TypeScript is a superset of JavaScript that introduces new features and helpful improvements to the language, which includes a powerful static typing system. By adding types in the code, we can avoid errors early and get rid of errors at compilation. In TypeScript, an interface is an abstract type that tells the compiler which property names an object can have. TypeScript creates implicit interfaces when an object is defined with properties. Interfaces define properties, methods, and, events that are the members of interfaces. They contain only the declaration of the members, and they are defined by the derived class.
Introduction
The TypeScript compiler uses an interface for type-checking whether the object describes a specific structure or not. Interfaces are used to validate objects passed as a parameter to a function. It is used to validate objects that are returned from a particular function. It is used to validate a specific structure of an entity. When the tsc compiles the code into JavaScript, then the interface will not be visible in the JavaScript file. Hence, the interface plays a vital role in the development phase only.
How To Declare TypeScript Interfaces
To declare interfaces in TypeScript, We use the interface keyword. The keyword must be followed by the interface name. The interface body contains the declaration of members and the variables.
Example for Declaring Interfaces:
Output
Working With Interfaces
We have seen how to declare interfaces, now we will see how they work for a few common use cases.
Specifying Optional Properties:
There are certain situations, where we would expect our objects to have optional properties. This can be achieved by placing a question mark ? just before the property's name during the declaration of the interface.
For Example:
In the above example, we can see that the interface Person contains two optional properties with the ? that are weight and hairColor while the other three properties age, name and, height are the required properties.
Extending an Interface
Interface in TypeScript can extend another interface and import its properties. The extends keyword is used to extend an interface. It allows us to copy the members from other named types and add new members to the final, more generic interface. We can also extend multiple interfaces by separating them with a comma. An interface can also extend a class, If the class contains private or protected members, it can only be implemented by a class or subclass of that class.
Main benefits of extending an interface:
- This helps in creating small and reusable components, as we don't have to copy the properties between interfaces.
- It signals the intent to the reader of the code that there is a relation between types.
Example of Extending an Interface:
Output
Optional Properties Of Interfaces
There are certain situations, where we would expect our objects to have optional properties. This can be achieved by placing a question mark ? just before the property's name during the declaration of the interface. It is very helpful to define interfaces in this way if we want to prevent the use of properties that are not included in the interface. In some cases, objects of the interface may or may not define the optional properties.
Example of specifying Optional Properties in an Interface:
Output
Read-only Properties Of Interfaces
In some cases, we have to restrict some attributes from being updated while creating an object. So, the read-only keyword will be used before specifying the property name to achieve this. This keyword makes a property read-only in the class, type, or interface. Read-only members can be accessed outside the class but their values cannot be changed. As they cannot be changed outside the class, hence they need to be initialized during the declaration or initialized inside the class constructor.
Example of Read-only Properties in an Interface:
In the above-given example, the aadharNo property is read-only. We define the personObj object of type Person and assign values to the two interface properties. After that, we tried to change the values of both attributes. Hence, the TypeScript compiler will throw an error when we change the aadharNo property as it is a read-only property.
Excess Property Checks
In TypeScript, Excess property checking is used when TypeScript checks the object to ensure that it doesn't contain any extra properties on top of what is defined in the type annotation for the object. This checking is triggered when object literals are defined with type annotations. It is useful for catching wrong typos and wrong property names.
Function Types
A function is a piece of code that executes some specific task. It is used to implement object-oriented programming concepts like Classes, Objects, Polymorphism, and Abstraction. It is used to ensure the reusability and maintainability of the code. A function type has two parts: parameters and return type. When we declare a function type, we have to specify both parts with the following syntax:
Here is an example that shows how to declare which has a function type that accepts two numbers and returns a number:
The function type accepts two arguments: x and y with the type number. The type of return value is number that follows the fat arrow => that appeared between parameters and return type.
Once assigning a variable with a function type, we can assign the function with the same type to the variable. TypeScript compiler will check the number of parameters along with their types and return type.
Here is an example to show how we can assign a function to a specific variable.
Also, we can declare a variable and pass a function to a variable.
If we assign other functions whose type doesn't match with the mul variable, the TypeScript compiler will throw an error:
In the above-given example, we reassigned a function whose type doesn't match the mul function variable.
Inferring function types:
TypeScript compiler can interpret the function type when you have the type on one side of the equation. This form of type inference is known as contextual typing.
In the above example, the add function will take the type (x: number, y: number) => number. Developers can reduce the amount of code with annotations by using type inference.
Indexable Types
Interfaces in TypeScript can also define indexable types. These types can be accessed via indexes. There are only two types of indexes in TypeScript: number and string. Indexable types have an index signature that defines the types we can use to index into the object, along with the corresponding return types when indexing.
Example
In the above example, the stringDemo interface has an index signature. This signature states that when a stringDemo is indexed with a number, it will return a string.
Indexable Types with Template Strings
A Template String is defined with backtick (`) characters, allowing for multi-line strings for string interpolation. Along with having normal strings, they contain other parts called placeholders that are embedded expressions defined by a dollar sign and curly braces: ${expression}. The strings and placeholders are passed to a function, either a default function or the function you pass. The default function just performs the string interpolation to do the substitution of placeholders and then concatenates the parts into a single string. A template string can also be used to indicate whether a particular pattern is allowed or not. For example, an HTTP headers object will have a set list of known headers and support of custom-defined properties that are prefixed with x-.
Example
Class Types In TypeScript
Class Types as Implementing an Interface
A class is defined as a blueprint for creating objects according to Object Oriented Programming. TypeScript gives built-in support for the concept of class. The class keyword is used to initialize a class. When we use the class keyword in TypeScript, we are creating two things with the same identifier:
- A TypeScript interface containing all the instance methods and properties of a class.
- A JavaScript variable with a different constructor function type.
Adding Type Properties to Classes:
In TypeScript, it is preferred to add non-method properties to classes and is required for the type system to understand what is available in the class.
In this example, id, name, and age are defined as the properties of the class. These properties do not have any value. TypeScript can warn and throw an error if a class property is not assigned a value directly on the definition, or within the constructor. A common problem in complex applications is how to keep related sets of functionality grouped. We have already achieved this by organizing code into modules for large sets of functionality. For example, if we had a Person class that accepted an attributes object:
In the above example, we have defined an anonymous type for the attributes parameter but this declaration is brittle. If we want to add some extra properties for the subclass Person, then we have to write the code for the entire type again and again. Also, we will not be able to reference this type in multiple places as it is an anonymous type assigned to a function parameter. To solve this problem, we use an interface in TypeScript to define the constructor arguments and export them alongside the class.
Now, we have a PersonProperties interface that can be referenced by our code as well as any other code that imports Person.
Difference between Static and Instance methods of Class
- Static Method: They belong to a class and they can't be called on an instance of the class. Rather, they are called on the class itself. They are utility functions that are used to create or clone objects. We use the static keyword to define static methods for a class.
Example:
- Instance Method: They belong to a class prototype that is inherited by all the instances of a class. They act on instances of a class and can be called on them. Methods that are not defined as static are instance methods.
Example:
Hybrid Types
TypeScript allows interfaces to represent hybrid types, i.e interfaces can have a combination of properties, function declaration, indexer, and methods. This flexibility allowed us to get aligned with JavaScript's dynamic nature.
Example of Implementing Hybrid Types in Interfaces:
Output:
Congratulations!
After reading this article, You can simply implement Interfaces and their various Properties and Applications in your TypeScript project and use them efficiently.
Conclusion
- We have seen how to declare an interface and its work along with the use cases. We can extend an interface in TypeScript using the extends keyword.
- We can choose whether or not to include certain properties with optional properties by adding ? in front of those properties.
- Read-only properties can be defined by readonly in front of the property.
- To describe excess properties within the objects, we can use [propName: string]: any; within the interface.
- We can implement interfaces with two types in classes: static and instance.
- Interfaces can be extended by other interfaces or classes and can be used to describe hybrid types that can be both a function and an object.
- Hope this article has provided you with information regarding the concept of Interfaces in TypeScript.