Skip to content
tsCheatSheet
GitHub

Generics

Generics enable the creation of “type variables” that facilitate the development of classes, functions, and type aliases without the requirement of explicitly specifying the types utilized by them.

Functions

function makePair<S, T>(varStr: S, varNum: T): [S, T] {
	return [varStr, varNum];
}
console.log(makePair<string, number>('This is your string, your num is:', 42));
// [ 'This is your string, your num is:', 42 ]

Types can also be inferred:

Classes

Genreics can be used to create classes with generalized properties and methods.

class NamedValue<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 NamedValue<number>('withNumber');
value.setValue(11);
console.log(value.toString()); // withNumber: 11

If used in a constructor paramter the type can be inferred:

Type aliases

Create reusable types with generics in type aliases.

type Wrapped<T> = { value: T };

const wrappedValue: Wrapped<number> = { value: 11 };
// also works with interfaces using syntax: `interface Wrapped<T> {`

Default Value

Assign default values to generics. These apply if no other type is inferred or specified.

class NamedValue2<T = string> {
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 value2 = new NamedValue2('myNumber');
value2.setValue('myValue');
console.log(value2.toString()); // myNumber: myValue

Extends

You can put constraints on the types that can be used with generics by using the extends keyword. Allows for more speicific typing. Works along with default values.

function createLoggedPair<S extends string | number, T extends string | number>(
	v1: S,
	v2: T
): [S, T] {
	console.log(`creating pair: v1='${v1}', v2='${v2}'`);
	return [v1, v2];
}
createLoggedPair('a', 1); // creating pair: v1='a', v2='1'