Advanced Types in TypeScript: Generics and Enums

November 30, 2023

In our previous posts, we have covered the basics of TypeScript, including setting up your development environment, understanding types, and using functions and classes. Now, it’s time to dive into more advanced concepts in TypeScript – generics and enums.

Generics are a powerful feature in TypeScript that allow for type flexibility and safety. They allow us to create reusable code that can work with a variety of data types. Let’s take a closer look at how generics work.

What are Generics?

Generics in TypeScript are a way to create functions or classes that can work with a variety of data types, rather than just one specific type. This allows us to write code that is more flexible and reusable.

Let’s say we have a function that takes in an array of numbers and returns the sum of all the numbers in the array. We could write this function to only work with numbers, like this:

function sumNumbers(arr: number[]): number {
let sum = 0;
for (let num of arr) {
sum += num;
}
return sum;
}

This function would work perfectly fine, but what if we wanted to use it with an array of strings? We would have to write a separate function to handle that case. This is where generics come in.

We can rewrite our function using generics, like this:

function sum(arr: T[]): T {
let sum = 0;
for (let num of arr) {
sum += num;
}
return sum;
}

Here, we have used the T placeholder to represent the type of data that will be passed in. This allows us to use our function with any type of data, not just numbers.

We can also specify the type of data that will be returned by using T as the return type. This ensures that our function will always return the same type of data that was passed in.

Using Generics with Classes

Generics can also be used with classes in TypeScript. This allows us to create classes that can work with different data types, similar to how we used them with functions.

Let’s say we have a Container class that can hold any type of data. We could write it like this:

class Container {
private data: any;

constructor(data: any) {
this.data = data;
}

getData(): any {
return this.data;
}
}

This class will work, but it doesn’t provide any type safety. We can improve it by using generics, like this:

class Container {
private data: T;

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

getData(): T {
return this.data;
}
}

Here, we have used the T placeholder to represent the type of data that our container will hold. This ensures that our container will only hold data of that type, and provides type safety when accessing the data.

Enums in TypeScript

Enums, short for enumerations, are a way to define a set of named constants in TypeScript. They allow us to create a collection of related values that can be easily referenced throughout our code.

Let’s say we have a program that deals with different colors. We could create an enum to represent all the possible colors, like this:

enum Color {
Red,
Blue,
Green
}

Here, we have defined three named constants – Red, Blue, and Green. We can then use these constants in our code, like this:

let favoriteColor = Color.Blue;

We can also assign values to our enum constants, like this:

enum Color {
Red = 1,
Blue = 2,
Green = 3
}

Now, the Blue constant will have a value of 2, and the rest of the values will increment by one.

Conclusion

Generics and enums are powerful features in TypeScript that allow for more flexible and reusable code. Generics provide type safety and flexibility, while enums allow us to define a set of related constants. By understanding and using these advanced types,