Skip to main content

Archive

Show more

Implementing Generics in Functions and Classes

Implementing Generics in Functions and Classes

Generics in TypeScript allow you to write flexible and reusable code by creating functions and classes that can work with any data type. By using generics, you can ensure type safety while working with a variety of types, making your code more robust and adaptable. This guide covers how to implement generics in functions and classes.


Generics in Functions

Generics in functions enable you to create reusable functions that can handle different types of inputs and outputs while maintaining type safety. Here’s how you can define and use generics in functions:

Defining a Generic Function

To define a generic function, use the function keyword followed by a type parameter in angle brackets <T>. The type parameter T represents the generic type:


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

console.log(identity(42)); // Output: 42
console.log(identity("Hello")); // Output: Hello

In this example, the identity function takes a parameter of type T and returns a value of the same type. The generic type T can be replaced with any specific type when calling the function.

Using Generic Functions with Different Types

Generic functions can be used with various types, ensuring type safety for different scenarios:


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

let result = merge({ name: "Alice" }, { age: 30 });
console.log(result); // Output: { name: 'Alice', age: 30 }

In this example, the merge function combines two objects of different types into one object, ensuring that the resulting type includes properties from both input objects.


Generics in Classes

Generics in classes allow you to create classes that can operate with different types while maintaining type safety. Here’s how you can define and use generics in classes:

Defining a Generic Class

To define a generic class, use a type parameter in angle brackets <T> after the class name:


class Box {
  private value: T;

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

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

let numberBox = new Box(123);
console.log(numberBox.getValue()); // Output: 123

let stringBox = new Box("Hello");
console.log(stringBox.getValue()); // Output: Hello

In this example, the Box class has a generic type T that is used for its internal value. The getValue method returns the value of the type T.

Using Generics with Class Methods

Generics can also be used within class methods to ensure type safety for various operations:


class Stack {
  private items: T[] = [];

  push(item: T): void {
    this.items.push(item);
  }

  pop(): T | undefined {
    return this.items.pop();
  }
}

let numberStack = new Stack();
numberStack.push(1);
numberStack.push(2);
console.log(numberStack.pop()); // Output: 2

let stringStack = new Stack();
stringStack.push("TypeScript");
console.log(stringStack.pop()); // Output: TypeScript

In this example, the Stack class uses generics to manage a stack of items. The push and pop methods operate on the type T, ensuring that the stack maintains type safety.


Conclusion

Implementing generics in functions and classes in TypeScript enhances code reusability and type safety. By defining and using generics, you can create flexible and adaptable components that work with various types while ensuring consistency and correctness in your code. Generics are a powerful feature in TypeScript that helps build robust applications with less redundancy.

Comments