Lesson 44 of 60 – Generic Functions
73%

Generic Functions in TypeScript

Generic functions are functions that can work with different data types while maintaining type safety. Instead of creating separate functions for every data type, you can create one reusable function using a generic type parameter.

Note: Generic functions are useful when the same operation needs to work with different types of data.

1. What is a Generic Function?

A generic function uses a type parameter so that the function can work with different types.

function identity<T>(
    value: T
): T {

    return value;
}

Here, T represents the type of the value.

2. Why Use Generic Functions?

Generic functions allow you to reuse the same function with multiple data types.

function identity<T>(
    value: T
): T {

    return value;
}

const name = identity("Amit");
const age = identity(25);

One function can handle both strings and numbers.

3. Generic Type Parameter

The generic type parameter is usually written inside angle brackets after the function name.

function display<T>(
    value: T
): T {

    return value;
}

T is a placeholder for a real type.

4. Generic Function with String

function identity<T>(
    value: T
): T {

    return value;
}

const result =
    identity<string>("Hello");

console.log(result);

In this example, T is explicitly set to string.

5. Generic Function with Number

function identity<T>(
    value: T
): T {

    return value;
}

const result =
    identity<number>(100);

console.log(result);

Here, T is explicitly set to number.

6. Generic Type Inference

TypeScript can often determine the generic type automatically from the function argument.

function identity<T>(
    value: T
): T {

    return value;
}

const name =
    identity("Rahul");

const age =
    identity(30);

You do not always need to write <string> or <number> explicitly.

7. Generic Function with Boolean

function identity<T>(
    value: T
): T {

    return value;
}

const result =
    identity(true);

console.log(result);

The type parameter T becomes boolean.

8. Generic Function with Array

function getFirst<T>(
    items: T[]
): T {

    return items[0];
}

const number =
    getFirst([10, 20, 30]);

const name =
    getFirst(["Amit", "Rahul"]);

The function works with arrays of different types.

9. Generic Function Returning an Array

function createArray<T>(
    value: T
): T[] {

    return [value];

}

const numbers =
    createArray(10);

const names =
    createArray("Amit");

The returned array keeps the type of the supplied value.

10. Generic Function with Two Parameters

function pair<T>(
    first: T,
    second: T
): T[] {

    return [first, second];

}

const numbers =
    pair(10, 20);

const names =
    pair("Amit", "Rahul");

Both arguments use the same generic type.

11. Function with Multiple Generic Types

A generic function can use multiple type parameters.

function createPair<T, U>(
    first: T,
    second: U
) {

    return {
        first,
        second
    };

}

const result =
    createPair("Amit", 25);

console.log(result);

12. Generic Function Returning an Object

function createObject<T>(
    value: T
) {

    return {
        value
    };

}

const result =
    createObject("TypeScript");

console.log(
    result.value
);

13. Generic Function with Objects

function getName<T extends {
    name: string
}>(user: T): string {

    return user.name;

}

const student = {
    name: "Amit",
    age: 20
};

console.log(
    getName(student)
);

The constraint ensures that the object has a name property.

14. Generic Function with Constraints

Use extends when a generic function requires certain properties or capabilities.

function getLength<
    T extends { length: number }
>(value: T): number {

    return value.length;

}

console.log(
    getLength("Hello")
);

console.log(
    getLength([1, 2, 3])
);

15. Generic Function with Interface Constraint

interface HasId {
    id: number;
}

function showId<
    T extends HasId
>(item: T): number {

    return item.id;

}

const student = {
    id: 101,
    name: "Amit"
};

console.log(
    showId(student)
);

16. Generic Function with keyof

The keyof operator allows a generic function to work safely with object properties.

function getProperty<
    T,
    K extends keyof T
>(
    object: T,
    key: K
): T[K] {

    return object[key];

}

const student = {
    name: "Amit",
    age: 20
};

const name =
    getProperty(student, "name");

const age =
    getProperty(student, "age");

17. Generic Function with Union Types

function display<T>(
    value: T
): T {

    return value;
}

const result =
    display<string | number>(
        "Hello"
    );

console.log(result);

A generic type parameter can also be explicitly assigned a union type.

18. Generic Callback Function

Generic functions can also be used with callback functions.

function processValue<T>(
    value: T,
    callback: (value: T) => void
): void {

    callback(value);

}

processValue(
    "Hello",
    value => {
        console.log(
            value.toUpperCase()
        );
    }
);

19. Generic Function with Promise

function createPromise<T>(
    value: T
): Promise<T> {

    return Promise.resolve(value);

}

const promise =
    createPromise("Hello");

promise.then(value => {

    console.log(
        value.toUpperCase()
    );

});

The promise preserves the generic type of the value.

20. Generic Function for API Data

interface ApiResponse<T> {
    data: T;
    success: boolean;
}

function createResponse<T>(
    data: T
): ApiResponse<T> {

    return {
        data,
        success: true
    };

}

const response =
    createResponse("Student loaded");

console.log(
    response.data
);

21. Generic Function for Student Data

interface Student {
    id: number;
    name: string;
}

function createStudentResponse<T>(
    data: T
): T {

    return data;

}

const student: Student = {
    id: 101,
    name: "Amit"
};

const result =
    createStudentResponse(student);

console.log(
    result.name
);

22. Generic Function for Searching

function findItem<T>(
    items: T[],
    condition: (item: T) => boolean
): T | undefined {

    return items.find(condition);

}

const students = [
    {
        id: 1,
        name: "Amit"
    },
    {
        id: 2,
        name: "Rahul"
    }
];

const student =
    findItem(
        students,
        item => item.id === 2
    );

console.log(student);

23. Generic Function for Mapping Data

function mapItems<T, U>(
    items: T[],
    callback: (item: T) => U
): U[] {

    return items.map(callback);

}

const numbers = [
    1, 2, 3
];

const strings =
    mapItems(
        numbers,
        number => String(number)
    );

console.log(strings);

Here, T represents the input type and U represents the output type.

24. Generic Function in React

Generic functions can be used inside React applications to create reusable type-safe logic.

function getFirst<T>(
    items: T[]
): T {

    return items[0];

}

const names =
    ["Amit", "Rahul"];

const firstName =
    getFirst(names);

25. Generic Function in React Native

Generic functions are useful in React Native when working with reusable data-processing functions.

function getFirstItem<T>(
    items: T[]
): T {

    return items[0];

}

const users = [
    {
        id: 1,
        name: "Amit"
    },
    {
        id: 2,
        name: "Rahul"
    }
];

const firstUser =
    getFirstItem(users);

console.log(
    firstUser.name
);

26. Generic Function with Default Type

A generic function can define a default type parameter.

function createValue<
    T = string
>(
    value: T
): T {

    return value;

}

const text =
    createValue("Hello");

const number =
    createValue<number>(100);

27. Generic Function with Tuple

Generic functions can preserve the types of multiple values inside a tuple.

function makePair<T, U>(
    first: T,
    second: U
): [T, U] {

    return [first, second];

}

const result =
    makePair(
        "Amit",
        25
    );

console.log(result);

28. Common Generic Function Mistakes

  • Using any when a generic type would be safer.
  • Creating unnecessary generic parameters.
  • Forgetting constraints when a property is required.
  • Using the wrong generic type parameter.
  • Making simple functions unnecessarily complex.
  • Ignoring the relationship between input and output types.

29. Complete Practical Example

interface Student {
    id: number;
    name: string;
    course: string;
}

function findStudent<T extends {
    id: number
}>(
    students: T[],
    id: number
): T | undefined {

    return students.find(
        student =>
            student.id === id
    );

}

const students: Student[] = [

    {
        id: 101,
        name: "Amit",
        course: "TypeScript"
    },

    {
        id: 102,
        name: "Rahul",
        course: "React Native"
    }

];

const student =
    findStudent(
        students,
        102
    );

if (student) {

    console.log(
        "Name:",
        student.name
    );

    console.log(
        "Course:",
        student.course
    );

}

This example uses a generic constraint to create a reusable student-search function.

30. Generic Functions Summary

Generic functions allow you to create reusable functions that work with different types while preserving type safety.

function identity<T>(
    value: T
): T {

    return value;
}

const name =
    identity("TypeScript");

const age =
    identity(25);

const active =
    identity(true);

Generic functions are an important foundation for advanced TypeScript programming and are widely used when building React and React Native applications.

📌 Key Points

  • Generic functions work with multiple data types.
  • T is commonly used as a generic type parameter.
  • TypeScript can often infer generic types automatically.
  • Generic functions can return generic types.
  • Generic functions can work with arrays.
  • Multiple generic parameters such as T and U can be used.
  • Generic constraints can be created with extends.
  • keyof can be combined with generic functions.
  • Generic functions can work with objects and interfaces.
  • Generics are useful for API response functions.
  • Generics can be used with callbacks and promises.
  • Generic functions are useful in React and React Native applications.
  • Generic functions preserve relationships between input and output types.

🧠 Quick Quiz

Question: Which syntax is commonly used to define a generic type parameter in a TypeScript function?