TypeScript Generics
TypeScript is a strongly-typed language that supports generics. Generics allow developers to create reusable code that can work with a variety of types, rather than a single specific type. This makes code more flexible and easier to maintain.
Generic Functions
TypeScript supports the creation of generic functions, which can work with a variety of types. Here is an example of a generic identity function:
function identity<T>(arg: T): T {
return arg;
}
T
is a type parameter that can be replaced with any type at the time the function is called. The type parameter is specified between angle brackets <>
immediately after the function name. The function takes a parameter arg
of type T
, and returns a value of type T
.
We can call the identity function with any type:
let output = identity<string>("myString"); // type of output will be 'string'
let output2 = identity<number>(123); // type of output2 will be 'number'
Generic Interfaces
TypeScript also supports the creation of generic interfaces. Here is an example of a generic interface:
interface GenericIdentityFn<T> {
(arg: T): T;
}
We can create a variable of this interface type, and assign a function that matches the signature:
let myIdentity: GenericIdentityFn<number> = identity;
Generic Classes
TypeScript also supports the creation of generic classes. Here is an example of a generic class:
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
We can create an instance of this class with any type:
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };
Generic Constraints
TypeScript allows developers to impose constraints on the types that can be used with a generic type parameter. This can be done using the extends keyword. Here is an example:
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
We define an interface Lengthwise
with a single member length
of type number
. We then define a generic function loggingIdentity
that takes a single argument of type T
, which must extend Lengthwise
. The function logs the length of the argument to the console, and returns the argument.
We can call this function with any argument that has a length property of type number:
loggingIdentity("hello"); // logs "5"
loggingIdentity([1, 2, 3]); // logs "3"
loggingIdentity({ length: 10, value: 3 }); // logs "10"
Using Type Parameters in Constraints
TypeScript also allows developers to use type parameters in generic constraints. Here is an example:
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
We can call this function with any object and property key:
let x = { a: 1, b: 2, c: 3 };
getProperty(x, "a"); // returns 1
getProperty(x, "b"); // returns 2
getProperty(x, "c"); // returns 3
Using Class Types in Constraints
TypeScript also allows developers to use class types in generic constraints. Here is an example:
function create<T>(ctor: { new(): T }): T {
return new ctor();
}
We can call this function with any constructor that has a zero-parameter constructor:
class MyClass {
constructor() {}
}
let myInstance = create(MyClass);
This page was updated on -
Found an error or have feedback on our docs?
Create an issue on GitHub and let us know! Your input helps improve our documentation for everyone in the community.
Report error, send feedback on Github