One key aspect of Generics is "Passing Type Arguments," which empowers us to create highly adaptable functions, classes, and interfaces that cater to a wide range of data types. In this piece of article, we will embark on a journey to understand the ins and outs of Passing Type Arguments, exploring its various applications and how it enhances code maintainability.
TypeScript allows us to add type parameters to functions using angle brackets '<>' and a single uppercase letter to represent the type parameter. For example:
function echo<T>(arg: T): T {
return arg;
}
In this example, T
is the type parameter, and it denotes the generic type that the function can work with.
We can assign default types to type parameters to provide more flexibility and handle scenarios where a specific type is not explicitly provided. This can be achieved by specifying the default type after the type parameter:
function getValueOrDefault<T = string>(value: T, defaultValue: T): T {
return value || defaultValue;
}
Here, if the type T
is not explicitly provided during the function call, it defaults to string
.
TypeScript has a remarkable ability to infer types from the arguments passed to generic functions. This allows us to write cleaner code without explicitly specifying type parameters.
function concatenate<T>(arr: T[], separator: string): string {
let result = arr.join(separator);
console.log(result)
return result
}
const fruits = ["apple", "banana", "orange", "kivi"];
const concatenatedFruits = concatenate(fruits, ", "); // Output: "apple, banana, orange, kivi"
In this example, TypeScript infers that the generic type T
is string
, as the array fruits
contains string elements.
Generics provide a powerful alternative to using the any
type, as they offer the flexibility of handling different data types while retaining type safety.
const fetchData = async <T>(url: string) => {
const data: T = await fetch(url).then((response) => response.json());
return data;
};
Here, the function fetchData
maintains type safety without resorting to using any
.
Imagine we are building an e-commerce platform with a shopping cart that handles various product types. Using Generics, we can write functions that are adaptable to different product data structures.