blogBlog

Typescript Generics with Examples of Daily Life Use

Hey there, fellow developers! 👋🏼

Today, we’re going to talk about one of the most powerful and flexible features of TypeScript — generics. If you’re not familiar with generics, don’t worry. In this post, we’ll break down what generics are, how they work, and why they’re so useful 🤝🏼. So sit back, grab a cup of coffee, and let’s dive into the world of TypeScript generics! 🤓

What’s that?

TypeScript Generics is a powerful feature that allows us to write reusable code with more type safety. In TypeScript, Generics allows us to define a type or a function that can work with different data types, without sacrificing type safety 🦾.

For many people, the best way to learn something new is by seeing it in action. Reading about a concept can be helpful, but applying it to a real-world example can help to solidify your understanding and make it feel more tangible. This is especially true when it comes to programming languages and frameworks. Seeing code snippets and examples of how a feature works can help you to not only understand how it works but also how it can be used in practice. Whether you’re learning TypeScript generics or any other programming concept, working through examples can make the learning process more engaging and enjoyable.

Lets get started!


Let’s say you want to write a function that takes an array and returns the first element. This function can work with any type of array, so it’s a perfect candidate for Generics. Here’s an example:

function getFirstElement<T>(arr: T[]): T | undefined {
  return arr[0];
}

const numbers = [1, 2, 3, 4];
const firstNumber = getFirstElement(numbers); // 1

const strings = ['foo', 'bar', 'baz'];
const firstString = getFirstElement(strings);

This code snippet demonstrates the use of TypeScript’s generics feature to create a function getFirstElement<T> that can operate on arrays of any type. The function takes an array of type T as input and returns the first element of the array of the same type T. If the array is empty, it returns undefined.

Let’s break down the code and explain it step by step:

function getFirstElement<T>(arr: T[]): T | undefined {
  return arr[0];
}

The function getFirstElement is defined with a generic type parameter T in angle brackets <>. This parameter allows the function to work with arrays of any type. The function takes an array arr of type T[] as input, which means it is an array of elements of type T. The function returns the first element of the array, which is also of type T. The return type of the function is defined using the union operator | to indicate that it can return either a value of type T or undefined.

const numbers = [1, 2, 3, 4];
const firstNumber = getFirstElement(numbers); // 1

const strings = ['foo', 'bar', 'baz'];
const firstString = getFirstElement(strings); // 'foo'

Two arrays are declared and initialized with some values. The first array numbers contains numeric values, and the second array strings contains string values. Two variables firstNumber and firstString are defined to store the result of calling the getFirstElement function with the respective arrays as arguments. The first call returns the first element of the numbers array, which is the number 1. The second call returns the first element of the strings array, which is the string 'foo'.


You can also use Generics with classes. Here’s an example of a simple Stack class that can work with any data type:

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

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

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

  isEmpty(): boolean {
    return this.items.length === 0;
  }
}

const numberStack = new Stack<number>();
numberStack.push(1);
numberStack.push(2);
numberStack.push(3);
console.log(numberStack.pop()); // 3

const stringStack = new Stack<string>();
stringStack.push('foo');
stringStack.push('bar');
stringStack.push('baz');
console.log(stringStack.pop()); // 'baz'

Let’s break down the code and explain it step by step:

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

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

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

  isEmpty(): boolean {
    return this.items.length === 0;
  }
}

The Stack class is defined with a generic type parameter T in angle brackets <>. This parameter allows the class to work with elements of any type. The class contains a private member variable items that is an array of type T[], which means it is an array of elements of type T. The class also contains three methods:

  • The push method takes an item of type T as input and adds it to the end of the items array.
  • The pop method removes and returns the last element of the items array, which is also of type T. The return type of the method is defined using the union operator | to indicate that it can return either a value of type T or undefined.
  • The isEmpty method returns a boolean value indicating whether the items array is empty.
const numberStack = new Stack<number>();
numberStack.push(1);
numberStack.push(2);
numberStack.push(3);
console.log(numberStack.pop()); // 3

const stringStack = new Stack<string>();
stringStack.push('foo');
stringStack.push('bar');
stringStack.push('baz');
console.log(stringStack.pop()); // 'baz'

Let’s get more serious with the following;

Read the rest of this post on Medium

;