Hello! Today we're going to explain an important concept in TypeScript: Generics. Generics are a powerful tool for solving type issues, enhancing code reusability and flexibility while maintaining type safety.
1. What are Generics?
Generics are part of the type system and a tool to provide flexibility to classes and functions. By using generics, you can abstract and reuse code while maintaining type information (i.e., what kind of data is passed to the code).
For example, consider the following generic function.
function identity<T>(arg: T): T {
return arg;
}
This function can be called by specifying a type.
let output = identity<string>("myString");
console.log(output); // "myString"
Also, you can use type inference to automatically infer the type from the argument.
let output = identity("myString");
console.log(output); // "myString"
2. The Advantages of Generics
The advantages of generics lie in maintaining type safety, code reusability, and self-documentation.
Type Safety
Using generics allows you to abstract code without limiting the types that functions or classes operate on, maintaining type safety at compile time.
For example, the following generic function getArrayItems
takes an array of any type as an argument and returns the array as it is. This function can be used with arrays of any type, such as number arrays, string arrays, object arrays, etc.
function getArrayItems<T>(arr: T[]): T[] {
return arr;
}
let numArray = getArrayItems<number>([1, 2, 3, 4]); // number[]
let strArray = getArrayItems<string>(['a', 'b', 'c']); // string[]
let objArray = getArrayItems<{ id: number }>([{ id: 1 }, { id: 2 }]); // { id: number }[]
Code Reusability
Using generics allows you to design functions or classes without relying on specific types, enabling the creation of general code that operates with various types.
For example, the following GenericNumber
class allows you to create both a version that operates with number
type and a version that operates with string
type from the same code.
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myNumber = new GenericNumber<number>();
myNumber.zeroValue = 0;
myNumber.add = function(x, y) { return x + y; };
let myString = new GenericNumber<string>();
myString.zeroValue = "";
myString.add = function(x, y) { return x + y; };
Self-Documentation
Generics improve code readability by showing what types functions or classes operate with, making it easier for other developers to understand the code.
3. Generics vs Any
The difference between any
type and generics lies in whether they maintain type safety. Using any
type might sacrifice type safety. On the other hand, using generics can enhance the reusability and flexibility of the code while maintaining type safety.
let myVariable: any = 'Hello';
myVariable = 10; // no error, but potentially unsafe!
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>("myString"); // output is of type string
As seen above, generics are a powerful tool for enhancing code flexibility and reusability and maintaining type safety. In general, it is recommended to use generics as much as possible to maintain type safety.
That's all for the explanation about TypeScript's generics. I hope this article will help you deepen your understanding of generics in TypeScript. For more detailed information, please refer to the official documentation. Happy Coding!
Top comments (0)