Skip to main content

Can you make a generic class?

What a generic class is

A generic class is a class in which one or more types (for example, T, U, K, V) are passed as parameters to make it flexible and type-safe.

It is not tied to a specific data type, but works with any type while keeping strict typing.


1. The simplest example

javascript
class Box<T> { private value: T; constructor(value: T) { this.value = value; } getValue(): T { return this.value; } }

Usage:

javascript
const box1 = new Box<number>(123); const box2 = new Box<string>("Hello"); console.log(box1.getValue()); // 123 console.log(box2.getValue()); // Hello

Here T is a generic parameter:

  • when creating Box<number>T = number,
  • when creating Box<string>T = string.

TypeScript makes sure the type stays consistent:

javascript
box1.getValue().toFixed(2); // OK, T = number box2.getValue().toUpperCase(); // OK, T = string

2. A generic class with several parameters

javascript
class Pair<K, V> { constructor(public key: K, public value: V) {} describe() { console.log(`Key: ${this.key}, Value: ${this.value}`); } } const pair = new Pair<string, number>("age", 30); pair.describe(); // Key: age, Value: 30

Here K is the key type, V is the value type. You can use any number of generic parameters.


3. A generic class with a constraint (extends)

You can constrain the type parameter so it matches a specific shape:

javascript
interface Identifiable { id: number; } class Repository<T extends Identifiable> { private items: T[] = []; add(item: T) { this.items.push(item); } findById(id: number): T | undefined { return this.items.find(i => i.id === id); } } const users = new Repository<{ id: number; name: string }>(); users.add({ id: 1, name: "Tim" }); users.add({ id: 2, name: "Alex" }); console.log(users.findById(2)); // { id: 2, name: 'Alex' }

Here T must be an object with id: number. This prevents errors if someone tries to add something without an id.


4. A generic class with a default type

You can set a default type in case none is provided when creating it:

javascript
class Storage<T = string> { private data: T[] = []; add(item: T) { this.data.push(item); } getAll(): T[] { return this.data; } } const s1 = new Storage(); // T = string (default) s1.add("one"); s1.add("two"); const s2 = new Storage<number>(); s2.add(10); s2.add(20);

5. Generic class + interfaces

Interfaces can be generic too, and classes can implement them:

javascript
interface IStorage<T> { add(item: T): void; getAll(): T[]; } class ArrayStorage<T> implements IStorage<T> { private data: T[] = []; add(item: T) { this.data.push(item); } getAll(): T[] { return this.data; } }

This way you can build "type-safe containers".


6. A generic class with inheritance

javascript
class BaseResponse<T> { constructor(public data: T, public success: boolean) {} } class ApiResponse<T> extends BaseResponse<T> { constructor(data: T, public status: number) { super(data, status >= 200 && status < 300); } } const response = new ApiResponse({ id: 1, name: "Tim" }, 200); console.log(response.data.name); // Tim

Generics can be inherited and passed further down the class hierarchy.


Summary

CapabilityExampleDescription
A simple genericclass Box<T> { ... }Types the contents
Several parametersclass Pair<K, V>Several types at once
A constraint<T extends SomeType>Restricts the allowed types
A default type<T = string>If no type is given
Implementing an interfaceclass A<T> implements I<T>Together with generic interfaces
Inheritanceclass B<T> extends A<T>Generics are passed further

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.