Generics allow you to write generic code that works with different types while maintaining strict type safety.
Syntax usage:
function identity<T>(value: T): T { return value; } const x = identity<string>('test'); // T = string
Where to apply:
Example with type constraint:
function getFirst<T extends { length: number }>(arr: T): T { return arr[0]; }
Question: Is it mandatory to specify a concrete type when calling a function with a Generic parameter?
Answer:
Not necessarily. TypeScript infers the types from the provided values when possible. However, sometimes it’s convenient to specify it explicitly, for example, when the type is unclear from the values or there are several options.
function identity<T>(value: T): T { return value; } identity(5); // T = number (auto) identity<string>('s'); // T = string (explicit)
Story
In an e-commerce project, a generic repository was written for different entities, but the type constraint was forgotten. As a result, any object could be passed, and at one point, an entity with incompatible fields was saved. Types did not protect against the error.
Story
A generic function was given an array, expecting an array with a specific element type. However, the function returned any[], as the generic was not explicitly specified and TypeScript couldn't infer the type. The error was only noticed in production.
Story
A junior developer created a generic class without a type constraint and used a field that didn’t exist in all types. The compiler didn't complain, but accessing the non-existent property broke all functionality.