Generics

Generics allow you to create templates for your types.

Example:

By using Generics you can relate an input parameter to an output parameter. The following code sets the type variable (T) to number when calling the generic function combine:

1
2
3
4
5
function combine<T>(a: T, b: T): T[] {
return [a, b];
}

combine<number>(1, 2); // [1, 2]

TypeScript supports type argument inference when passing the input values:

1
2
3
4
5
function combine<T>(a: T, b: T): T[] {
return [a, b];
}

combine(1, 2); // [1, 2]

You can also specify multiple type variables:

1
2
3
4
5
function combine<X, Y>(a: X, b: Y): (X | Y)[] {
return [a, b];
}

combine(1, '2'); // [1, "2"]

Default type variables are supported as well:

1
2
3
4
5
6
function combine<X, Y = string>(a: X, b: Y): (X | Y)[] {
return [a, b];
}

// It became optional to pass a type argument for `Y`:
combine<number>(1, '2'); // [1, "2"]

It is also possible to enforce a certain structure on your generic types using the extends keyword:

1
2
3
4
5
function combine<T extends { name: string }>(a: T, b: T): T[] {
return [a, b];
}

combine({name: 'Benny', type: 'Pet'}, {name: 'Sofia'});

Generics also work in classes:

1
2
3
4
class KeyValuePair<Value> {
public key: string | undefined;
public value: Value | undefined;
}