Generics in TypeScript provide a way to create reusable and flexible components. They allow you to write functions, classes, and interfaces that can work with a variety of types rather than a single one.
Generics are particularly useful for creating functions or classes that work with collections of objects or other types where the type is not known until runtime.
For instance, you have some data coming from an API, where you could either get the data as string or number, based on that, you would need to do some calculations.
Here's a breakdown of how generics work in TypeScript:
1. Generic Functions
You can create a function that works with any type by using a generic type parameter. This parameter acts as a placeholder for the actual type.
In this example, the function identity takes an argument of type T and returns a value of the same type. When you call the function, you can specify the type, or TypeScript can infer it.
2. Generic Interfaces
You can define interfaces that use generics to describe a variety of shapes and behaviors.
Here, the GenericIdentityFn interface describes a function that takes an argument of type T and returns a value of type T.
3. Generic Classes
Classes can also use generics to create flexible and reusable components.
In this example, the GenericNumber class can work with any type, not just numbers. You can create instances of the class with different types.
4. Generic Constraints
Sometimes, you might want to restrict the types that can be used in your generics. You can achieve this using constraints.
In this example, the loggingIdentity function works only with types that have a length property. This is enforced by the extends Lengthwise constraint.
5. Default Type Parameters
You can specify default types for generic parameters.
In this example, the createArray function has a default type of string, so if no type is provided, it assumes the type is string.
Generics enhance the reusability and flexibility of your code, making it more robust and easier to maintain. They are a powerful feature of TypeScript that can significantly improve the quality of your codebase.