Generics enable the creation of ‘type variables’ that can be used in classes, functions, and type aliases without explicitly defining the types they use.
Generics facilitate writing reusable code.
Generics with functions allow for more generalized methods that accurately represent the types used and returned.
function createPair<S, T>(v1: S, v2: T): [S, T] { return [v1, v2]; } console.log(createPair<string, number>(‘hello’, 42)); // [‘hello’, 42] |
TypeScript can infer the type of the generic parameter based on the function parameters.
Generics can be used to create generalized classes, such as Map
.
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>(‘myNumber’); value.setValue(10); console.log(value.toString()); // myNumber: 10 |
TypeScript can also infer the type of the generic parameter when it is used in a constructor parameter.
Generics in type aliases enable the creation of more reusable types.
type Wrapped<T> = { value: T }; const wrappedValue: Wrapped<number> = { value: 10 }; |
This also applies to interfaces, using the following syntax: interface Wrapped<T> {.
Generics can be assigned default values, which are used if no other value is specified or inferred.
class NamedValue<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 value = new NamedValue(‘myNumber’); value.setValue(‘myValue’); console.log(value.toString()); // myNumber: myValue |
Constraints can be added to generics to limit what types are allowed. These constraints enable reliance on a more specific type when using the generic type.
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]; } |
This can be combined with a default value for the generic type.