Table of contents
1.
Introduction
2.
Generics Syntax
3.
Generic Interfaces
4.
Implementation of Generic Interfaces
4.1.
Generic interfaces that describe object properties
4.2.
Generic interfaces that describe methods
4.3.
 
4.4.
Generic interfaces that describe index types
5.
Frequently Asked Questions (FAQs)
6.
Key Takeaways
Last Updated: Mar 27, 2024

Generic Interfaces

Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Source: Link

Introduction

TypeScript is a superset of JavaScript.

TypeScript builds on top of JavaScript. First, you write the TypeScript code. Then, you compile the TypeScript code into plain JavaScript code using a TypeScript compiler.

Once you have the simple JavaScript code, you can deploy it to any environment that JavaScript runs.

TypeScript files use the .ts extension rather than the .js extension of JavaScript files.

One of the most crucial part of designing programmes is to create reusable components. This guarantees the program's long-term flexibility and scalability.

Generics is a useful tool for creating reusable components. Generics allow components to work with any data type rather than being limited to a single data type. As a result, components can be utilised with a wide range of data types. Generics in TypeScript are very similar to generics in C#.

Generics Syntax

Before diving into generics, this lesson will go through the TypeScript generics syntax, followed by an example to demonstrate its general function.

Generics appear inside angle brackets in TypeScript code, with the syntax <T>, where T denotes a passed-in type. <T> can be interpreted as a type T generic. In this scenario, 'T' will act as placeholders for a type defined when an instance of the structure is produced, similar to how parameters in functions work. As a result, the generic types supplied inside angle brackets are also referred to as generic type parameters or simply type parameters. Multiple generic types, such as T, K, and A, can also appear in a single definition.

Note: To name a generic type, programmers commonly use a single letter as a convention. This is not a TypeScript syntax rule, and you can name generics just like any other type, but it helps to signal to folks reading your code that a generic type does not require a specific type.

Generics can be found in functions, types, classes, and interfaces, among other places. Each of these structures will be discussed more in this blog, but a function will now be used to demonstrate generics' basic syntax.

Consider the following scenario: We have a JavaScript function with two parameters: an object and an array of keys. The function will produce a new object based on the original but only contains the keys you specify.

function pickObjectKeys(obj, keys) {
 let result = {}
 for (const key of keys) {
   if (key in obj) {
     result[key] = obj[key]
   }
 }
 return result
}

As shown in this example, the pickObjectKeys() function iterates over the keys array and creates a new object using the keys supplied in the array.

The following is an example about how to use the function.

const language = {
 name: "TypeScript",
 age: 8,
 extensions: ['ts', 'tsx']
}

const ageAndExtensions = pickObjectKeys(language, ['age', 'extensions'])

The pickObjectKeys() function isolates the age and extensions properties after declaring an object language. The following is the value of ageAndExtensions.

{
 age: 8,
 extensions: ['ts', 'tsx']
}

You'd have to utilise generics if you wanted to convert this code to TypeScript and make it type-safe. The following highlighted lines might be added to the code to refactor it.

function pickObjectKeys<T, K extends keyof T>(obj: T, keys: K[]) {
 let result = {} as Pick<T, K>
 for (const key of keys) {
   if (key in obj) {
     result[key] = obj[key]
   }
 }
 return result
}

const language = {
 name: "TypeScript",
 age: 8,
 extensions: ['ts', 'tsx']
}

const ageAndExtensions = pickObjectKeys(language, ['age', 'extensions'])

 

<T, K extends keyof T> specifies two argument types for the function, with K getting a type equal to the union of the keys in T. The obj function parameter is then set to the type T, and keys to an array of the type K. Because T sets age as a number and extensions as an array of strings in the language object, the variable ageAndExtensions will now be given the type of an object with the values age: number and extensions: string[].

This imposes a return type based on the pickObjectKeys parameters, giving the function the ability to enforce a typing structure before it knows what type it needs to enforce. This also improves the developer experience when using the method in an IDE(Integrated Development Environment) like Visual Studio Code, which will generate key parameter suggestions depending on the object you supply. This can be seen in the screenshot below.

TypeScript suggestion based on the type of the object

With a basic understanding of how generics are formed in TypeScript, you can move on to investigating how generics can be used in certain contexts. The first section of this blog will go over how generics can be utilised in functions.

Generic Interfaces

Like classes, interfaces also can be generic. A generic interface has a generic type parameter list in angle brackets <> following the name of the interface.

interface interfaceName<T> {
 // ...
}

The type parameter T becomes visible to all members of the interface due to this. There can be one or more types in the type parameter list, as an example.

interface interfaceName<U,V> {
 // ...
}

Implementation of Generic Interfaces

Let's look at some generic interface declaration examples.

Generic interfaces that describe object properties

The examples below demonstrate how to declare a generic interface with two members, key and value, and the accompanying types K and V.

interface Pair<K, V> {
 key: K;
 value: V;
}

You can now define any key/value pair with any type using the Pair interface. Consider the following scenario.

let month: Pair<string, number> = {
 key: 'Jun',
 value: 6
};

console.log(month);

In this example, we define a month key-value pair with a string as the key and a number as the value.

 

Generic interfaces that describe methods

A generic interface with two functions, add() and remove(), is declared as follows.

interface Collection<T> {
 add(o: T): void;
 remove(o: T): void;
}

The Collection<T> generic interface is implemented by this List<T> generic class.

class List<T> implements Collection<T>{
 private items: T[] = [];

 add(o: T): void {
     this.items.push(o);
 }
 remove(o: T): void {
     let index = this.items.indexOf(o);
     if (index > -1) {
         this.items.splice(index, 1);
     }
 }
}

You can create a list of values of various types, such as numbers or strings, using the List<T> class.

For example, the following code demonstrates about how to generate a list of numbers using the List<T> generic class.

let list = new List<number>();

for (let i = 0; i < 10; i++) {
   list.add(i);
}

 

Generic interfaces that describe index types

The following declares an interface that describes an index type.

interface Options<T> {
 [name: string]: T
}

let inputOptions: Options<boolean> = {
 'disabled': false,
 'visible': true
};

Frequently Asked Questions (FAQs)

1. What is typescript?

TypeScript is a JavaScript-based, strongly typed programming language that provides improved tooling at any size.

2. What is a generic interface?

A generic interface has a generic type parameter list in angle brackets <> following the interface's name.

Key Takeaways

In this article, we learned about the generics in the Typescript. We learnt about the generic syntax of the Typescript. We also learned how to implement generic interfaces and different ways of implementing them.

You can refer to more articles available on Typescript.

Happy Learning!

 

Live masterclass