What Are Generics in TypeScript?

TypeScript Generics Explained with Easy Examples

A generic in TypeScript is a way to write reusable code that works with different types without hardcoding them.

It’s not a variable or a function — it’s a type placeholder like <T> that lets you plug in a real type later.

function identity<T>(arg: T): T {
  return arg;
}

let a = identity<string>("Hello");
let b = identity<number>(123);

Here, T is just a placeholder for a type. You can reuse the same function with different types.


Explained Simply

function identity<T>(arg: T): T {
  return arg;
}
  • T is not a variable. It’s a type parameter.
  • arg is a regular variable, but its type depends on the type you pass in.
  • identity is a function that uses a generic to work with any type.

This lets you write flexible code that works with many types without repeating the same logic.


A Generic Is a Feature, Not a Function

Generics are not functions — they’re a feature that lets you use type placeholders to make your code reusable and type-safe.

You’re basically telling TypeScript:

“I don’t know the exact type yet, but when this code is used, I’ll fill it in.”


Analogy: Cookie Cutter

Imagine a function is like a cookie cutter.

  • Use vanilla dough (type string) → you get a string.
  • Use chocolate dough (type number) → you get a number.

The cutter stays the same. Only the dough (type) changes. That’s the power of generics.


Generics in Interfaces

interface Box<T> {
  content: T;
}

let stringBox: Box<string> = { content: "hello" };
let numberBox: Box<number> = { content: 42 };

Generics in Classes

class Container<T> {
  value: T;
  constructor(value: T) {
    this.value = value;
  }
}

const c = new Container<boolean>(true);

Generics with Arrays

function getFirstElement<T>(arr: Array<T>): T {
  return arr[0];
}

const firstString = getFirstElement<string>(["apple", "banana", "cherry"]);
const firstNumber = getFirstElement<number>([10, 20, 30]);

Array<T> is a built-in generic. You can also write it as T[].


Restricting Generic Types

You can use extends to make sure T has certain properties.

function getLength<T extends { length: number }>(item: T): number {
  return item.length;
}

getLength("hello");         // OK
getLength([1, 2, 3]);       // OK
getLength({ length: 99 });  // OK
// getLength(123); ❌ Error: number doesn’t have length

Multiple Type Parameters

function mergeObjects<T, U>(obj1: T, obj2: U): T & U {
  return { ...obj1, ...obj2 };
}

const result = mergeObjects({ name: "Alice" }, { age: 30 });

This combines the properties of both objects into one.


Default Generic Type

function createList<T = string>(items: T[]): T[] {
  return items;
}

const list1 = createList(["a", "b", "c"]);       // T = string (default)
const list2 = createList<number>([1, 2, 3]);     // T = number

You can set a default type so that it’s used when the caller doesn’t specify one.


Common Question

Does a generic create a “universal variable”?

No. A generic creates a structure (like a function or class) where types are filled in later. It’s not a variable itself.

  • T is a type placeholder, not a value.
  • Generics only exist at compile time for type checking.
  • They disappear in the final JavaScript code.

Leave a Reply

Your email address will not be published. Required fields are marked *