Suggest an editImprove this articleRefine the answer for “extends in generic parameters”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)`extends` in generic parameters (`function example<T extends Constraint>(value: T)`) is a constraint that `T` must satisfy; TypeScript checks whether `T` can be considered a subtype of `Constraint`. **Key point:** this is not class inheritance, it is a logical type constraint that guarantees the presence of required properties and improves type inference.Shown above the full answer for quick recall.Answer (EN)Image## 1. General form ```javascript function example<T extends Constraint>(value: T) { ... } ``` - `T` is the type parameter (generic). - `extends Constraint` is the constraint that `T` must satisfy. TypeScript checks whether `T` can be considered a subtype of `Constraint`. If not, the compiler throws an error. --- ## Example 1: a shape constraint ```javascript function printLength<T extends { length: number }>(value: T) { console.log(value.length); } printLength("hello"); // a string has length printLength([1, 2, 3]); // an array has length printLength(123); // a number does not have length ``` > Here `T` must be a type that has a `length: number` property. --- ## Example 2: a base-type constraint ```javascript function toStringValue<T extends string | number>(value: T): string { return value.toString(); } toStringValue("abc"); // string toStringValue(123); // number toStringValue(true); // boolean is not part of the allowed union ``` > Here `T` is constrained by the union: `string | number`. --- ## Example 3: an interface constraint ```javascript interface Identifiable { id: string; } function logId<T extends Identifiable>(obj: T) { console.log(obj.id); } logId({ id: "123", name: "Tim" }); // OK logId({ name: "Alex" }); // missing id ``` > `T` is required to contain an `id` field. --- ## Example 4: dependent generic parameters ```javascript function getProp<T, K extends keyof T>(obj: T, key: K) { return obj[key]; } const user = { id: 1, name: "Tim" }; getProp(user, "id"); // OK getProp(user, "age"); // "age" is not a key of user ``` > Here `K` depends on `T` and is constrained to only the object's allowed keys. --- ## Example 5: a constraint for classes and constructors ```javascript type Constructor<T> = new (...args: any[]) => T; function createInstance<T extends Constructor<any>>(Ctor: T) { return new Ctor(); } ``` > `T` must be a constructor (a class) so that it can be instantiated via `new`. --- ## Example 6: a constraint for dictionaries (`Record`) ```javascript function sumValues<T extends Record<string, number>>(obj: T): number { return Object.values(obj).reduce((a, b) => a + b, 0); } sumValues({ a: 1, b: 2 }); // OK sumValues({ x: 1, y: "two" }); // a string, not number ``` > `Record<string, number>` means: an object whose keys are strings and values are numbers. --- ## Example 7: extends + a default value ```javascript function identity<T extends string | number = string>(value: T): T { return value; } identity("hi"); // OK identity(42); // OK identity(true); // boolean does not satisfy the constraint ``` --- ## What `extends` actually does in generic parameters 1. **Constrains the substitutable type** - `T` must *extend* (be a subtype of) the given type. 2. **Guarantees properties** - you can access them without errors. 3. **Improves type inference** - TS knows more about the possible structure of `T`. 4. **Does not create inheritance!** - it is not the `extends` from classes, but a *logical type constraint*. --- ## Example without `extends` -> an error ```javascript function getLength<T>(value: T): number { return value.length; // TS Error: T might not have length } ``` Fixed: ```javascript function getLength<T extends { length: number }>(value: T) { return value.length; // OK } ``` --- ## Summary | Purpose of `extends` | Example | What it provides | | --- | --- | --- | | Shape constraint | `<T extends { id: string }>` | Guarantees the presence of fields | | Union constraint | `<T extends string \| number>` | Only the listed types | | Interface constraint | `<T extends Identifiable>` | Only types that implement the interface | | Parameter dependency | `<K extends keyof T>` | The key must belong to the object | | Class constraint | `<T extends new (...args) => any>` | Only constructors | | Dictionary constraint | `<T extends Record<string, number>>` | Objects with a defined value type |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.