advanced · 24 minute study
Generics preserve relationships
A reusable function should preserve what it knows about the caller's data instead of returning any or a vague union.
Useful preparation · 1 prerequisite
Use this as a map, not a lock. If these ideas are familiar, continue.
- Compatible shapes, excess properties and shallow readonly — Knowing what structural typing does and does not guarantee prevents accidental mutation and misplaced confidence in 'exact' objects.
First, build a mental model
A type parameter is an unknown chosen by the caller that remains consistent within one call. A constraint describes operations you may perform on that unknown.
- T captures the caller's specific type.
- K extends keyof T restricts keys to properties that exist.
- T[K] retrieves the property's type, preserving the input/output relationship.
- Use a generic when it connects positions; a needless type parameter creates work without knowledge.
function pick<T, K extends keyof T>(value: T, key: K): T[K] {
return value[key];
}
const order = { id: 'demo', quantity: 3, paid: false };
const quantity = pick(order, 'quantity');
const paid = pick(order, 'paid');
// pick(order, 'missing');- Infer T
T is the specific shape of order for this call.
- Constrain K
The string 'quantity' is a valid key of T.
- Return T[K]
The result is number for quantity and boolean for paid.
Production thinking
Take this beyond the example.
Prefer small generic helpers with concrete call-site inference over elaborate type puzzles. Test empty inputs and runtime boundaries separately.
Sources and further reading
Your evidence
unseen is a local learning signal, not a credential or proof of production competence.
Explain the mental model, then explicitly acknowledge it. Opening a page is not evidence.
Supported retries can complete this lesson. Independent evidence and delayed review determine the skill stage.
Next lesson · Derive contracts without copying fields →