How to create reusable code templates using TypeScript generics
TypeScript generics are used to generate reusable and type-safe code. The system can be applied to functions, classes, interfaces and types, among other things.
What are TypeScript generics?
In almost every programming language, there are tools that allow users to create code templates that can then be reused later on or in other projects. The aim is not only to save time, but also to create secure code that can be seamlessly integrated into new environments. Different components, functions and complete data structures can be written and replicated in this way without losing their type safety. In TypeScript, these tasks are performed with generics. Types can therefore be passed on as parameters to other types, functions or other data structures.
Syntax and functionality using a simple example
The basis for working with TypeScript generics are generic variables. These function as a kind of placeholder and specify the data type that is to be declared at a later point in time. In the code, they are marked with any capital letter. When creating the code, these variables are enclosed in angle brackets. They are assigned the actual type name so that the desired TypeScript function, interface or TypeScript class moves in place of the placeholder. This placeholder is also referred to as a type parameter. It is also possible to place several of these type parameters within a bracket. You can recognise the syntax of TypeScript generics from this simple example:
function ExampleFunction<T>(parameter1: T): void {
console.log(`The data type of the parameter ${parameter1} is: ${typeof parameter1}`)
}
typescriptHere we use the name of the function (‘ExampleFunction’) to define the generic variable ‘T’. In the following code, we declare this variable as a string:
ExampleFunction<string>("Here is a string.");
typescriptNow, when we pass the parameter value string
to the function, we get the following output:
The data type of the parameter Here is a string. is: string
typescriptTypeScript Generics with two variables
TypeScript generics work in a very similar way when two or more generic variables are used as placeholders. In the following example, we store the variables ‘T’ and ‘U’ as types for the parameters ‘parameter1’ and ‘parameter2’. They are separated from each other by a comma:
function ExampleFunction<T, U>(parameter1: T, parameter2: U): string {
return JSON.stringify({parameter1, parameter2});
}
typescriptNow we assign data types and values to the two placeholders. In this case, the data types are number
and string
, along with the values ‘11’ and ‘Player’. Here is the appropriate code:
const str = ExampleFunction<number, string>(11, "Player");
console.log(str);
typescriptExamples of reproducible classes
It is also possible to use TypeScript generics to create reproducible classes. In the following example, we use generics to output a number. This is the appropriate code:
class NumericalValue<T> {
private _value: T | undefined;
constructor(private name: string) {}
public setValue(value: T) {
this._value = value;
}
public getValue(): T | undefined {
return this._value;
}
public toString(): string {
return `${this.name}: ${this._value}`;
}
}
let value = new NumericalValue<number>('myValue');
value.setValue(11);
console.log(value.toString());
typescriptThis will give you the following output:
myValue: 11
typescriptThe principle also works with other data types and several generic variables. You can see this in the following example:
class ExampleClass<T, U> {
firstName: T;
lastName: U;
constructor(firstName: T, lastName: U) {
this.firstName = firstName;
this.lastName = lastName;
}
}
typescriptNow we assign the data type string
and the intended values to the variables:
const person1 = new ExampleClass<string, string>("Julia", "Brown");
console.log(`${person1.firstName} ${person1.lastName}`)
typescriptThis time the following is output:
Julia Brown
typescriptIf you want to combine different data types, proceed as in the following example:
class ExampleClass<T, U> {
number: T;
word: U;
constructor(number: T, word: U) {
this.number = number;
this.word = word;
}
}
typescriptThe placeholders are now assigned the data types number
and string
as well as their values:
const combination = new ExampleClass<number, string>(11, "Player");
console.log(`${combination.number} ${combination.word}`);
typescriptThis is what is output:
11 Player
typescriptUsing it with interfaces
The use of TypeScript generics is also possible and even recommended for interfaces. The procedure is similar to declaring a class:
interface Interface<T> {
value: T;
}
typescriptNow we implement the interface in the class ‘ExampleClass’. We assign the data type string
to the variable ‘T’:
class ExampleClass implements Interface<string> {
value: string = "Here is an example with an interface";
}
const output = new ExampleClass();
console.log(output.value)
typescriptThe output looks as follows:
Here is an example with an interface
typescriptHow to create generic arrays
TypeScript generics can also be used for TypeScript arrays. Here is a simple code example in which we use the reverse
function to reverse the number sequence of an array:
function reverse<T>(array: T[]): T[] {
return array.reverse();
}
let numbers: number[] = [10, 7, 6, 13, 9];
let newSeries: number[] = reverse(numbers);
console.log(newSeries);
typescriptWe receive this output as a result:
[9, 13, 6, 7, 10]
typescriptTypeScript generics for conditional types
Lastly, we’ll demonstrate how to use conditional types with TypeScript generics. The outcome will vary depending on whether a specific condition is met. In this example, the condition is that the data type must be string
. Here’s the code:
type IsThisAString<T> = T extends string ? true : false;
type A = "example";
type B = {
name: string;
};
type FirstResult = IsThisAString<A>;
type SecondResult = IsThisAString<B>;
typescripttype A
is therefore the string ‘example’, while type B
is an object with the property ‘name’ and the data type string
. We then assign these two types to ‘FirstResult’ and ‘SecondResult’. When we check the two types, we will find that ‘FirstResult’ receives the value true
as a string, while ‘SecondResult’ remains false
.
Deployment directly via GitHub: Deploy Now from IONOS is the best choice for websites and apps alike, thanks to automatic framework detection, quick setup, and optimal scalability. Choose the right package for your project!