Learn how to constrain generic type parameters using the extends keyword to guarantee specific property availability.
Discover how TypeScript infers types automatically and how let versus const declarations shape wide types versus narrow literal types.
By default, a generic type parameter <T> can be absolutely anything (number, string, object, array). But what if your function needs to access a specific property (like .length or .id) on T?
extends Constraint KeywordUse Generic Constraints (<T extends Requirement>) to constrain generic parameters so they must satisfy a specific interface or type shape:
interface HasLength {
length: number;
}
// T is constrained to types that have a numeric '.length' property
function logLength<T extends HasLength>(item: T): T {
console.log(`Length is: ${item.length}`);
return item;
}
logLength("Hello World"); // Valid! (strings have .length)
logLength([1, 2, 3, 4]); // Valid! (arrays have .length)
logLength({ length: 10 });// Valid!
// logLength(12345); // Error: Type 'number' does not have a '.length' property!
keyofEnsure a property key exists on an object parameter using <K extends keyof T>:
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { id: 101, name: "Alex", isOnline: true };
const nameValue = getProperty(user, "name"); // Type: string
const idValue = getProperty(user, "id"); // Type: number
// getProperty(user, "invalidKey"); // Error: Argument of type '"invalidKey"' is not assignable to "id" | "name" | "isOnline"
<T extends Shape>, extends means "T is assignable to Shape", NOT class inheritance!Constrain generic parameters when accessing properties. Next, let's explore Discriminated Unions and Pattern Matching!