Accept values with a required structural capability while preserving their precise types.
Generic APIs
TypeScript · Const
extends constrains generic type parameters and forms the assignability test in conditional types. In conditional types, it selects one of two branches and can distribute over unions.
In a generic declaration, extends constrains a type parameter to types assignable to a required shape. In a conditional type, it tests assignability and selects the true or false branch; when the checked type is a naked type parameter, the conditional distributes across union members.
T extends U ? X : Y
function f<T extends Constraint>(value: T): T| Name | Type | Description |
|---|---|---|
T | type parameter | The type being constrained or tested. |
U | type | The target type used for the constraint or assignability test. |
For a conditional type, the selected branch type; for a constrained generic declaration, the declared generic result.
extends after a generic type parameter to require a structural capability, such as a length property.?; a failed test selects the branch after :.interface HasLength { length: number }
function logLength<T extends HasLength>(value: T): T {
console.log(value.length);
return value;
}
const text = logLength("hello");
const items = logLength([1, 2, 3]);The constraint permits values with a length property while preserving each argument's specific type.
Generic APIs
Type-level branching
Union transformations
extends do in a generic constraint?In a generic constraint such as T extends Lengthwise, T may be any type assignable to Lengthwise. The constraint allows the implementation to use the required properties while retaining the caller's more specific type.
Follow-up: How can distribution be prevented in a conditional type? Wrap both sides of the check in tuple types, such as [T] extends [U] ? X : Y, so the checked parameter is no longer naked.
extends work in a conditional type?A conditional type has the form T extends U ? X : Y. It produces X when T is assignable to U; otherwise it produces Y.
Follow-up: What happens when T is a union? If T is naked in the check, TypeScript evaluates each union member separately and unions the results.
A conditional type can defer its result when type variables prevent TypeScript from deciding assignability immediately. Once sufficient type information is available, it resolves to the true or false branch.
Follow-up: Can conditional types infer a component of a matched type? Yes; an infer declaration inside the extends pattern introduces a type variable whose inferred type can be used in the result.
genericsconditional typesinferdistributive conditional typesgeneric constraints