Generics in TypeScript allow you to write flexible and reusable functions, classes, and interfaces while maintaining type safety. With generics, you can specify the types used in a function or class when you call them, rather than hardcoding the types.

Example: Using Generics

1. Without Generics (Using a specific type)

function identity(arg: number): number {
  return arg;
}
  • In the above example, the function identity takes a number as an argument and returns a number. It is specific to the number type.

2. Using any (Less Type Safety)

function identity(arg: any): any {
  return arg;
}
  • In this case, the any type is used, meaning the function can accept any type as input and return any type. While this approach provides flexibility, it sacrifices type safety.

3. Using Generics (Type-safe and Flexible)

function identity<T>(arg: T): T {
  return arg;
}
  • Here, T is a generic type parameter. This allows the function identity to accept an argument of any type and return a value of the same type. The type of T will be inferred based on the argument passed to the function.

4. Calling the Generic Function

let output = identity<string>("myString");
console.log(output);  // Output: "myString"
  • When calling identity, we specify that T is of type string by writing <string> after the function name. The function now accepts and returns a string.
  • The type of output will be inferred to be string.

Key Points:

  1. Generic Function Syntax:

    • The function identity is declared with a generic type parameter T. This allows it to work with any type passed as an argument, and the return type will be the same type as the input.
  2. Calling Generic Functions:

    • You can specify the type argument explicitly (e.g., <string>) or allow TypeScript to infer it automatically based on the argument provided.
  3. Type Safety with Generics:

    • The use of generics ensures that the argument and return type are consistent. For example, if you pass a string to identity, it will only return a string.