Skip to main content

Archive

Show more

Generics in TypeScript

Generics in TypeScript

Generics in TypeScript are a powerful feature that allows you to create reusable and flexible components by defining types that can be specified later. They enable you to write functions, classes, and interfaces that work with a variety of types while maintaining type safety.


Introduction to Generics

Generics provide a way to create components that work with any data type. You can define a generic type in a function, class, or interface, and specify the actual type when using the component. This ensures that the type information is preserved and enforced, making your code more robust and reusable.


Generic Functions

Generic functions allow you to define a function that can work with any type. You use a type parameter to represent the type that will be specified when the function is called:


function identity(value: T): T {
  return value;
}

let num = identity(42);        // Type is number
let str = identity("Hello");   // Type is string

In this example, the identity function uses a generic type parameter T to represent the type of the value parameter and return type. The type of num is inferred as number, and the type of str is inferred as string.


Generic Classes

Generic classes allow you to create classes that can work with different types. You define a type parameter in the class definition and use it within the class:


class Box {
  private value: T;

  constructor(value: T) {
    this.value = value;
  }

  getValue(): T {
    return this.value;
  }
}

let numberBox = new Box(123);
let stringBox = new Box("Hello");

console.log(numberBox.getValue()); // Output: 123
console.log(stringBox.getValue()); // Output: Hello

In this example, the Box class is defined with a generic type parameter T. The value property and getValue method use this type parameter. Instances of Box are created with specific types, such as number and string.


Generic Interfaces

Generic interfaces allow you to define interfaces that work with multiple types. You use a type parameter in the interface definition and specify the type when implementing the interface:


interface Pair {
  key: K;
  value: V;
}

let pair: Pair = {
  key: 1,
  value: "TypeScript"
};

console.log(pair.key);   // Output: 1
console.log(pair.value); // Output: TypeScript

Here, the Pair interface is defined with two generic type parameters, K and V. An instance of Pair is created with number as the key type and string as the value type.


Using Multiple Type Parameters

Generics can also handle multiple type parameters, allowing you to define more complex relationships between types:


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

let result = merge({ name: "Alice" }, { age: 25 });

console.log(result); // Output: { name: 'Alice', age: 25 }

The merge function takes two objects of different types and returns a new object that combines both types. The return type T & U represents the intersection of the two types.


Conclusion

Generics in TypeScript provide a powerful way to create reusable and type-safe components. By using generic functions, classes, and interfaces, you can write code that works with various types while ensuring type safety and consistency. Understanding and using generics effectively can help you build more flexible and maintainable applications.

Comments