TypeScript Fundamentals

Type Inference & Annotations

TypeScript infers types from values, assignments, control flow, and usage. Annotations are most valuable at boundaries where they document intent and prevent accidental API drift.
  • Inference is usually best for local values
  • Annotations are valuable at boundaries
  • Return annotations can prevent accidental widening
  • Contextual typing flows inward
  • satisfies checks without losing useful literals
Where to annotate
LocationDefault choiceWhy
Local constInferInitializer is nearby
Function parameterAnnotateCaller contract
Exported returnOften annotatePublic API stability
Callback parameterLet context inferConsumer API knows shape
Config objectUse satisfiesCheck shape while preserving literals
Boundary annotations, local inference
type User = { id: string; name: string }

export function formatUser(user: User): string {
  const label = `${user.name} (${user.id})` // inferred string
  return label
}

const routes = {
  home: { path: "/", auth: false },
  admin: { path: "/admin", auth: true },
} satisfies Record<string, { path: string; auth: boolean }>
The API is explicit; local implementation stays clean.
Sources
  • The TypeScript HandbookEveryday Types
  • Effective TypeScript, 2nd EditionType inference
  • TypeScript ReferenceType compatibility