Foundations of Advanced Generics: Parameters and Constraints

TypeScript generics are crucial for building flexible, reusable, and type-safe code that works across various data types without losing type information. This introductory lesson will cover generic type parameters and constraints, foundational concepts for advanced TypeScript.

Understanding Generic Type Parameters

A generic type parameter (e.g., T, U) acts as a placeholder for a concrete type determined at usage. For example, function identity<T>(arg: T): T { return arg; } accepts an argument of type T and returns that exact type. If called with identity("hello"), its return type is string; with identity(123), it's number. This maintains type safety while offering flexibility.

Applying Generic Constraints

While generic type parameters provide flexibility, constraints ensure those types possess specific properties or methods. Using the extends keyword, a constraint limits a generic parameter to types assignable to a specified base type. This guarantees safe operations. For instance, function logLength<T extends { length: number }>(item: T): void { console.log(item.length); } constrains T to types with a length: number property. Calls like logLength("example") or logLength([1, 2, 3]) are valid. However, logLength(10) results in a type error since a number lacks a length property.

Mastering these foundations is key to TypeScript's potential. The next lesson will explore powerful type transformations using conditional and mapped types.