Magic of TypeScript Generics
Tags: webdev, javascript, typescript, programming
Published: 2024-01-18 05:53:44

## Introduction

Welcome, fellow developers, to the mystical realm of TypeScript Generics! 🚀 If you've ever felt the need to write code that dances gracefully across various data types without compromising on type safety, you're in for a treat. TypeScript Generics are like the spell-book of a code wizard, allowing you to conjure powerful, reusable, and type-safe components. Let me take you to the enchanting world of Generics!

## Chapter 1: The Essence of Generics

At the heart of TypeScript Generics is the ability to create functions that transcend the boundaries of data types. Imagine a function that echoes whatever you pass into it, regardless of its type. Behold, the identity function:


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

// Usage
let result = identity<string>("Hello, generics!");
console.log(result); // Output: Hello, generics!
```


## Chapter 2: Generics Unleashed - Classes Edition

Not just confined to functions, Generics can also spice up your classes. Meet the mysterious Box:


```
class Box<T> {
  private value: T;

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

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

// Usage
let numberBox = new Box<number>(42);
console.log(numberBox.getValue()); // Output: 42

let stringBox = new Box<string>("Generics are powerful!");
console.log(stringBox.getValue()); // Output: Generics are powerful!

```

The Box class is like a magical container, preserving the essence of its contents, no matter the type.

## Chapter 3: Generics and Interfaces - A Harmonious Duo

Interfaces, too, can dance with Generics in perfect harmony. Behold the majestic Pair:

```
interface Pair<T, U> {
  first: T;
  second: U;
}

// Usage
let pair: Pair<number, string> = { first: 1, second: "two" };
console.log(pair.first); // Output: 1
console.log(pair.second); // Output: two
```

A Pair of Generics, creating a bond between two different types - the Romeo and Juliet of TypeScript.

## Chapter 4: Constraints - Taming the Generics Beast

Sometimes, you need a bit of control over your generic types. Enter constraints, the noble knights of type safety:

```
interface Lengthwise {
  length: number;
}

function logLength<T extends Lengthwise>(arg: T): void {
  console.log(arg.length);
}

// Usage
logLength("Hello"); // Output: 5
logLength([1, 2, 3]); // Output: 3
```

The Lengthwise interface is like a magic circle, ensuring that only objects with a length property can step inside.

## Chapter 5: Default Values - When Generics Get Lazy

Generics can also be a bit lazy. This is one of my favourite among all. Just **set a default value**, and let TypeScript do the work:

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

// Usage
let result = identity("Hello, generics!");
console.log(result); // Output: Hello, generics!
```


No need to shout the type every time; TypeScript's got it covered.

## Conclusion

Remember this: Generics are your magical companions, ready to adapt to any type and make your code more versatile than a chameleon at a colour factory. Embrace the power, wield it wisely, and let the enchantment of Generics elevate your coding spells to new heights! Happy coding, wizards! See you on the next one. Do follow if you have learned something new. 🪄✨