DEV Community

Cover image for TypeScript’s Most Important Concept, Made Stupidly Simple(Generics!)(11)
Karandeep Singh for Wisdom Bits

Posted on

TypeScript’s Most Important Concept, Made Stupidly Simple(Generics!)(11)

Today! We’re going to continue TypeScript learning like you’re a smart 5-year-old who loves to build things and asks “why?” (which is the best thing ever).

& yes “why?” is my way of learning.

I've divided this into 20 Chapters. and will go one by one and each will be of 2 - 3 min. of read.
This is a Continuation. if you have not read the Previous chapter -
Chapter 10

Real Production Use - present in the end of Article.

🧩 Chapter 11: Generics – Magic Boxes That Work for Anything

(aka: “Reusable, type-safe superpowers without repeating yourself.”)

In TypeScript, Generics are these magic boxes:

They let you write one function or type that can work with any type while keeping type safety. Not clear🤔 Let's understand with examples, then will break it down...


🧪 Example 1: Identity Function

A function that returns what you give it:

function identity<T>(value: T): T { // syntax
  return value;
}
Enter fullscreen mode Exit fullscreen mode

Here:

  • <T> is a type variable (magic box)
  • Whatever type you pass in (number, string, etc.), TS knows it will return the same type.

Usage:

let num = identity(5);         // num: number
let str = identity("hello");   // str: string
Enter fullscreen mode Exit fullscreen mode

🧪 Example 2: Generics in Arrays

Imagine you want to get the first element of any array:

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

let firstNum = firstElement([1, 2, 3]);        // number
let firstStr = firstElement(["a", "b", "c"]);  // string
Enter fullscreen mode Exit fullscreen mode

✅ Works for any array type
Returns the correct type automatically


🧩 Example 3: Generics in Types

You can create generic types too.

type Box<T> = {
  value: T;
};

let box1: Box<number> = { value: 100 };
let box2: Box<string> = { value: "Karan" };
Enter fullscreen mode Exit fullscreen mode

🔧 Example 4: Generics with Constraints

What if you want your generic to only accept types with specific properties?

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

getLength("hello");          // ✅ string has length
getLength([1, 2, 3]);        // ✅ array has length
getLength(123);              // ❌ number doesn't have length
Enter fullscreen mode Exit fullscreen mode

🛠️ Real Production Use: React Components

type ListProps<T> = {
  items: T[];
  renderItem: (item: T) => JSX.Element;
};

function List<T>({ items, renderItem }: ListProps<T>) {
  return <div>{items.map(renderItem)}</div>;
}
Enter fullscreen mode Exit fullscreen mode

🌼 What does this do?

You are building a reusable List component that:
✅ Can render any type of list (numbers, strings, users, products)
✅ Knows exactly what type it is rendering
✅ Keeps type safety and auto-complete while using it in your app


🔧 Breaking it down:

type ListProps<T> = {...}

  • We create a generic type alias called ListProps.
  • <T> makes it generic so it can adapt to any item type you pass.
  • It has:

    • items: T[] → An array of any type T you will provide.
    • renderItem: (item: T) => JSX.Element → A function you give to render each item of type T into React elements.

function List<T>(...) {...}

We define a generic React component:

  • <T> lets this component adapt to any type you pass.
  • It accepts props of type ListProps<T>, ensuring that:

    • The items array contains only items of type T.
    • The renderItem function receives exactly type T.

🚀 How do you use it?

Example B: Rendering a list of users

type User = {
  id: number;
  name: string;
};

<List
  items={[
    { id: 1, name: "Karan" },
    { id: 2, name: "Wisdom Bits" },
  ]}
  renderItem={(user) => <div key={user.id}>{user.name}</div>}
/>
Enter fullscreen mode Exit fullscreen mode

✅ Here, T is inferred as User.


Why is this powerful in production?

Reusability:
You write List once and use it everywhere without rewriting for each type.

Type Safety:
If you try to access a non-existent property on user, TS will catch it.

Cleaner UI Components:
You abstract common rendering patterns while keeping them type-safe.


🎯 In one line:

Using Generics in React like this allows you to build reusable, type-safe UI components that adapt to any data structure while maintaining strong TypeScript protection.

Recap

Concept Example Meaning
Generic variable <T> Placeholder for any type
In functions function<T>(param: T): T Works with any type
In types type Box<T> = { value: T } Box can hold any type
With constraints <T extends { length: number }> Only types with length allowed

Read Previous Chapters

If you enjoyed this and want to master TypeScript and other technologies, follow the series and drop a like!🤝

I’m a passionate software developer sharing the cool things I discover, hoping they help you level up on your coding journey.

How i created my own State Management Library : Rethinking State Management in React — From a Dev, for Developers.

Top comments (0)