Performance hosting for your React / Next.js applications → here!
5 min read

TypeScript Generics: The Ultimate Guide, 2025

Andru K. profile picture
by Andre K. [full-stack developer]
Hi guys,
in this article we will look at Typescript Generics, what they are and how to use them. Oops!
Generics in TypeScript are a powerful tool for writing reusable, type-safe code. Whether you're a beginner or an experienced developer, mastering generics will level up your TypeScript skills.
In this complete guide, you'll learn:
  • What generics are and why they matter
  • How to use generics in functions, interfaces, and classes
  • Real-world examples with best practices
  • Advanced patterns (conditional types, mapped types, and more)
By the end, you'll confidently use generics like a TypeScript pro. Fasten your seatbelts, let's dive in!

1. What Are Generics in TypeScript?

Generics allow you to write flexible and reusable components without sacrificing type safety. Instead of using any, generics let you preserve types while working with different data structures.

Why Use Generics?

  1. Avoid code duplication – Write one function that works with multiple types.
  2. Better type inference – Get autocompletion and error checking.
  3. Safer than any – Maintain strict typing without runtime errors.

Basic Generic Example


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

    // Usage
    const output = identity("Hello Generics from ITsoftMake.COM!"); // Type: string
    const numOutput = identity(42); // Type: number

Here, <T> is a type variable that captures the input type.

2. Using Generics in Functions

Generic Functions


    function logAndReturn<T>(value: T): T {
        console.log(value);
        return value;
    }

    const result = logAndReturn(23); // Logs: 23

Multiple Type Parameters


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

    const merged = merge({ name: "Andre" }, { age: 30 }); // { name: "Alice", age: 30 }

3. Generics in Interfaces and Classes

Generic Interfaces


    interface ApiResponse<T> {
        data: T;
        status: number;
    }

    const userResponse: ApiResponse<{ name: string }> = {
        data: { name: "Ritesh" },
        status: 200,
    };

Generic Classes


    class DataStorage<T> {
        private data: T[] = [];

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

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

    const stringStorage = new DataStorage<string>();
    stringStorage.addItem("TypeScript Generics - Hi from ITsoftMake.COM");

4. Advanced Generic Patterns

Default Generic Types


    function fetchData<T = string>(url: string): Promise<T> {
        return fetch(url).then(res => res.json());
    }

Constraints with extends


    interface HasId {
        id: number;
    }

    function getById<T extends HasId>(items: T[], id: number): T | undefined {
        return items.find(item => item.id === id);
    }

Conditional Types


    type CheckNumber<T> = T extends number ? "Yes" : "No";
    type A = CheckNumber<42>; // "Yes"
    type B = CheckNumber<"TS">; // "No"

5. Real-World Use Cases

API Wrappers (Fetch with Type Safety)


    async function fetchUser<T>(userId: string): Promise<T> {
        const response = await fetch(`/api/users/${userId}`);
        return response.json();
    }

    const user = await fetchUser<{ name: string }>("123");

Utility Functions (e.g. map, filter)


    function mapArray<T, U>(arr: T[], mapper: (item: T) =>U): U[] {
        return arr.map(mapper);
    }

    const numbers = [1, 2, 3];
    const doubled = mapArray(numbers, x=> x * 2); // [2, 4, 6]

6. Common Mistakes & Best Practices

NO Overusing any type instead of generics → Loses type safty.
YES Use constraints (extends) when needed → Ensures correct types.
NO Complex nested generics → Hard to read.
YES Keep generics simple and well-documented. Yeees!!!

Conclusion

Generics make TypeScript scalable and maintainable. By using them effectively, you can:
  • Write reusable functions and classes
  • Improve type safety over any
  • Handle complex data structures elegantly
Next Step: Try implementing generics in your projects!