Type­Script generics are used to generate reusable and type-safe code. The system can be applied to functions, classes, in­ter­faces and types, among other things.

What are Type­Script generics?

In almost every pro­gram­ming 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 seam­less­ly in­te­grat­ed into new en­vi­ron­ments. Different com­po­nents, functions and complete data struc­tures can be written and repli­cat­ed in this way without losing their type safety. In Type­Script, these tasks are performed with generics. Types can therefore be passed on as pa­ra­me­ters to other types, functions or other data struc­tures.

Syntax and func­tion­al­i­ty using a simple example

The basis for working with Type­Script generics are generic variables. These function as a kind of place­hold­er 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 Type­Script function, interface or Type­Script class moves in place of the place­hold­er. This place­hold­er is also referred to as a type parameter. It is also possible to place several of these type pa­ra­me­ters within a bracket. You can recognise the syntax of Type­Script generics from this simple example:

function ExampleFunction<T>(parameter1: T): void {
    console.log(`The data type of the parameter ${parameter1} is: ${typeof parameter1}`)
}
type­script

Here we use the name of the function (‘Ex­am­ple­Func­tion’) to define the generic variable ‘T’. In the following code, we declare this variable as a string:

ExampleFunction<string>("Here is a string.");
type­script

Now, 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
type­script

Type­Script Generics with two variables

Type­Script generics work in a very similar way when two or more generic variables are used as place­hold­ers. In the following example, we store the variables ‘T’ and ‘U’ as types for the pa­ra­me­ters ‘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});
}
type­script

Now we assign data types and values to the two place­hold­ers. In this case, the data types are number and string, along with the values ‘11’ and ‘Player’. Here is the ap­pro­pri­ate code:

const str = ExampleFunction<number, string>(11, "Player");
console.log(str);
type­script

Examples of re­pro­ducible classes

It is also possible to use Type­Script generics to create re­pro­ducible classes. In the following example, we use generics to output a number. This is the ap­pro­pri­ate 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());
type­script

This will give you the following output:

myValue: 11
type­script

The 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;
	}
}
type­script

Now 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}`)
type­script

This time the following is output:

Julia Brown
type­script

If 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;
	}
}
type­script

The place­hold­ers 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}`);
type­script

This is what is output:

11 Player
type­script

Using it with in­ter­faces

The use of Type­Script generics is also possible and even rec­om­mend­ed for in­ter­faces. The procedure is similar to declaring a class:

interface Interface<T> {
	value: T;
}
type­script

Now we implement the interface in the class ‘Ex­am­ple­Class’. 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)
type­script

The output looks as follows:

Here is an example with an interface
type­script

How to create generic arrays

Type­Script generics can also be used for Type­Script 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);
type­script

We receive this output as a result:

[9, 13, 6, 7, 10]
type­script

Type­Script generics for con­di­tion­al types

Lastly, we’ll demon­strate how to use con­di­tion­al types with Type­Script 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>;
type­script

type 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 ‘FirstRe­sult’ and ‘Sec­on­dResult’. When we check the two types, we will find that ‘FirstRe­sult’ receives the value true as a string, while ‘Sec­on­dResult’ remains false.

Tip

De­ploy­ment 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 scal­a­bil­i­ty. Choose the right package for your project!

Go to Main Menu