Open In App

TypeScript Generic Classes

Last Updated : 18 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will learn about Generic Classes. Generics, allow a user to flexibly write the code and make reusable components which further ensures the scalability and flexibility of the program or the code for a long time. In TypeScript, you can create generic classes to define classes that can work with different data types while maintaining type safety. Generic classes allow you to write reusable code that can operate on a variety of data types without sacrificing type checking.

Syntax

class ClassName<T, U, ...> {
    // Class members and methods here
}

Parameters

  • ClassName: This is the name you give to your generic class.
  • <T, U, …>: These are the type parameters enclosed in angle brackets (<>). You can have multiple type parameters separated by commas (T, U, and so on).

Note

  • These type parameters serve as placeholders for specific data types.
  • You can use any valid identifier (e.g., T, U, KeyType, ValueType) as type parameters.
  • You can also use default types for type parameters, like <T = string, U = number>.
  • You can have as many type parameters as needed to represent the number of different data types your class will work with.

Example 1: In this example, Stack<T> is a generic class where T represents the type of elements stored in the stack. The class has methods like push, pop, peek, and isEmpty that work with elements of type T. This allows you to create stacks of different data types while ensuring type safety. Here, we can create instances of the Stack class for different types (e.g., number, string), and the TypeScript compiler will enforce type safety for operations involving the stack elements.

Javascript




class Stack<T> {
    private items: T[] = [];
  
    push(item: T): void {
        this.items.push(item);
    }
  
    pop(): T | undefined {
        return this.items.pop();
    }
  
    peek(): T | undefined {
        return this.items[this.items.length - 1];
    }
  
    isEmpty(): boolean {
        return this.items.length === 0;
    }
}
  
const numberStack = new Stack < number > ();
numberStack.push(1);
numberStack.push(2);
console.log(numberStack.pop()); // 2
  
const stringStack = new Stack < string > ();
stringStack.push("hello");
stringStack.push("world");
console.log(stringStack.pop()); // "world"


Output:

2
"world"

Example 2: In this example, Pair<T, U> is a generic class that takes two type parameters T and U, representing the data types of the first and second values. The class has a constructor that accepts values of types T and U. The getFirst() and getSecond() methods allow you to retrieve the first and second values, respectively. Here, we can create instances of the Pair class with different data types, and the TypeScript compiler ensures that the types of values match the specified type parameters. The output demonstrates how you can access the values of the pairs based on their data types.

Javascript




class Pair<T, U> {
    constructor(private first: T, private second: U) { }
  
    getFirst(): T {
        return this.first;
    }
  
    getSecond(): U {
        return this.second;
    }
}
  
// Creating instances of the 
// Pair class with different data types
const stringAndNumberPair = 
    new Pair < string, number> ("Hello", 42);
const booleanAndStringPair = 
    new Pair < boolean, string> (true, "World");
  
// Accessing the values
console.log(stringAndNumberPair.getFirst()); // Output: "Hello"
console.log(stringAndNumberPair.getSecond()); // Output: 42
  
console.log(booleanAndStringPair.getFirst()); // Output: true
console.log(booleanAndStringPair.getSecond()); // Output: "World"


Output:

"Hello" 
42 
true
"World"

Reference: https://www.typescriptlang.org/docs/handbook/2/generics.html#generic-classes



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads