DEV Community

Cover image for πŸ‘¨β€πŸ’» Understanding Generics in TypeScript with Practical Examples
Artem Turlenko
Artem Turlenko

Posted on

2

πŸ‘¨β€πŸ’» Understanding Generics in TypeScript with Practical Examples

Generics are one of the most powerful features in TypeScript, enabling developers to write flexible and reusable code. They allow you to create functions, interfaces, and classes that work with various data types while maintaining type safety. Let's explore TypeScript Generics with some practical examples.


What are Generics?

Generics provide a way to make your components work with multiple types rather than a single one. They help maintain strong typing while keeping your code flexible and reusable.

Basic Example of Generics

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

let output1 = identity<string>("Hello World"); // type string
let output2 = identity<number>(42); // type number
Enter fullscreen mode Exit fullscreen mode

Using Generics with Arrays

Generics can also be used to create flexible functions that handle arrays of any type:

function getArray<T>(items: T[]): T[] {
  return new Array<T>().concat(items);
}

let numArray = getArray<number>([1, 2, 3]);
let strArray = getArray<string>(["a", "b", "c"]);
Enter fullscreen mode Exit fullscreen mode

Generics with Interfaces

Interfaces become even more powerful when combined with generics:

interface KeyValuePair<K, V> {
  key: K;
  value: V;
}

let pair1: KeyValuePair<number, string> = { key: 1, value: "One" };
let pair2: KeyValuePair<string, boolean> = { key: "isAdmin", value: true };
Enter fullscreen mode Exit fullscreen mode

Generic Classes

Generic classes can handle various types and improve reusability significantly:

class GenericStorage<T> {
  private storage: T[] = [];

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

  getItems(): T[] {
    return [...this.storage];
  }
}

const numberStorage = new GenericStorage<number>();
numberStorage.addItem(1);
numberStorage.addItem(2);

const items = numberStorage.getItems(); // [1, 2]
Enter fullscreen mode Exit fullscreen mode

Constraints in Generics

Sometimes, you need generics to be limited to specific types using constraints:

interface Lengthwise {
  length: number;
}

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

logLength("Hello"); // Works fine
logLength([1, 2, 3]); // Also works fine
// logLength(10); // Error: number doesn't have a length property
Enter fullscreen mode Exit fullscreen mode

Conclusion

Generics provide incredible flexibility, allowing TypeScript developers to build scalable, type-safe, and reusable components. Embracing generics helps you write cleaner, safer, and more maintainable code.

Have you used generics in your projects? What are your favorite use cases? Let's share and learn together in the comments! πŸš€

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

πŸ‘‹ Kindness is contagious

DEV is better (more customized, reading settings like dark mode etc) when you're signed in!

Okay