codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🔷

TypeScript

27 / 60 topics
25Generics in TypeScript26Generic Functions27Generic Classes28Generic Interfaces29Type Constraints
Tutorials/TypeScript/Generic Classes
🔷TypeScript

Generic Classes

Updated 2026-04-20
3 min read

Introduction

Generics are a powerful feature in TypeScript that allow you to create reusable components and functions that can work with different types without losing type safety. In this section, we will explore how to use generics with classes in TypeScript.

What Are Generics?

Generics enable you to write flexible and reusable code by allowing parameters for types. This means you can define a class or function that operates on a variety of types while still maintaining type safety. Generics are denoted by angle brackets (<>) and are used to specify the type parameter(s) of a generic class.

Defining Generic Classes

To create a generic class, you need to declare one or more type parameters within angle brackets after the class name. These type parameters can then be used throughout the class definition.

Example: A Simple Generic Class

Let's define a generic class called Box that can hold any type of value:

class Box<T> {
  private content: T;

  constructor(value: T) {
    this.content = value;
  }

  getContent(): T {
    return this.content;
  }

  setContent(value: T): void {
    this.content = value;
  }
}

In this example, T is a type parameter that represents the type of the content stored in the box. The constructor and methods use this type parameter to ensure type safety.

Using the Generic Class

You can create instances of the Box class with different types:

const stringBox = new Box<string>('Hello, world!');
console.log(stringBox.getContent()); // Output: Hello, world!

const numberBox = new Box<number>(42);
console.log(numberBox.getContent()); // Output: 42

const booleanBox = new Box<boolean>(true);
console.log(booleanBox.getContent()); // Output: true

Each instance of the Box class is type-safe and can only store values of the specified type.

Multiple Type Parameters

You can also define generic classes with multiple type parameters. This is useful when you need to work with more than one type within the class.

Example: A Pair Class

Let's create a generic class called Pair that holds two related values of different types:

class Pair<K, V> {
  private key: K;
  private value: V;

  constructor(key: K, value: V) {
    this.key = key;
    this.value = value;
  }

  getKey(): K {
    return this.key;
  }

  getValue(): V {
    return this.value;
  }
}

In this example, K and V are type parameters representing the types of the key and value, respectively.

Using the Pair Class

You can create instances of the Pair class with different types for the key and value:

const stringNumberPair = new Pair<string, number>('age', 25);
console.log(stringNumberPair.getKey()); // Output: age
console.log(stringNumberPair.getValue()); // Output: 25

const booleanStringPair = new Pair<boolean, string>(true, 'yes');
console.log(booleanStringPair.getKey()); // Output: true
console.log(booleanStringPair.getValue()); // Output: yes

Type Constraints

Type constraints allow you to restrict the types that can be used with a generic class. This is useful when you need to ensure that certain operations are valid for the type parameter.

Example: A Lengthy Class

Let's create a generic class called Lengthy that only works with types that have a length property:

class Lengthy<T extends { length: number }> {
  private item: T;

  constructor(item: T) {
    this.item = item;
  }

  getLength(): number {
    return this.item.length;
  }
}

In this example, the type parameter T is constrained to types that have a length property.

Using the Lengthy Class

You can create instances of the Lengthy class with types that have a length property:

const stringLengthy = new Lengthy<string>('Hello');
console.log(stringLengthy.getLength()); // Output: 5

const arrayLengthy = new Lengthy<number[]>([1, 2, 3]);
console.log(arrayLengthy.getLength()); // Output: 3

Default Type Parameters

TypeScript allows you to specify default types for type parameters. This is useful when you want to provide a sensible default type that can be overridden if needed.

Example: A Container Class with Default Type

Let's create a generic class called Container with a default type parameter:

class Container<T = string> {
  private items: T[];

  constructor() {
    this.items = [];
  }

  addItem(item: T): void {
    this.items.push(item);
  }

  getItems(): T[] {
    return this.items;
  }
}

In this example, the type parameter T has a default value of string.

Using the Container Class

You can create instances of the Container class with or without specifying the type:

const stringContainer = new Container<string>();
stringContainer.addItem('Hello');
console.log(stringContainer.getItems()); // Output: ['Hello']

const numberContainer = new Container<number>();
numberContainer.addItem(42);
console.log(numberContainer.getItems()); // Output: [42]

const defaultContainer = new Container();
defaultContainer.addItem('Default');
console.log(defaultContainer.getItems()); // Output: ['Default']

Best Practices

  1. Use Descriptive Type Parameter Names: Choose meaningful names for your type parameters to make the code more readable and maintainable.
  2. Limit Type Constraints: Only constrain type parameters when necessary to avoid unnecessary restrictions that could limit flexibility.
  3. Provide Default Types: Use default types for type parameters to simplify usage and provide sensible defaults.

Conclusion

Generics are a powerful feature in TypeScript that allow you to create flexible and reusable classes. By using type parameters, multiple type parameters, type constraints, and default types, you can write code that is both generic and type-safe. Understanding how to use generics effectively will help you write more robust and maintainable TypeScript applications.

Further Reading

  • TypeScript Handbook: Generics
  • Advanced TypeScript: Generics

By following the examples and best practices outlined in this tutorial, you should be well-equipped to use generics with classes in your TypeScript projects.


PreviousGeneric FunctionsNext Generic Interfaces

Recommended Gear

Generic FunctionsGeneric Interfaces