Generics parameterize a type, a function or an interface with one or more types, written for example <T>. They let you write reusable code without losing type precision: the input type is carried over to the output. You can constrain them with extends.
Example
function premier<T>(xs: T[]): T | undefined {
return xs[0];
}
const n = premier([1, 2, 3]); // number | undefined