0Pricing
TypeScript Academy · Lesson

Contextual Typing: Inference from Context

Understand how TypeScript infers types from surrounding context.

Contextual Typing: Inference from Context is a free TypeScript Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What Is Contextual Typing?

Contextual typing occurs when TypeScript infers the type of an expression based on the position it appears in — the context provides the type, not the value itself.

document.addEventListener("click", (e) => {
  // e is inferred as MouseEvent from the event type
  console.log(e.clientX);
});

Contextual Typing in Callbacks

When you pass a callback to a typed function, TypeScript infers parameter types from the expected callback signature.

const nums = [1, 2, 3];
nums.forEach((n) => {
  // n inferred as number from Array<number>
  console.log(n.toFixed(2));
});

Contextual Typing and Object Literals

When an object literal is assigned to a typed variable, its property types are inferred from that type, enabling precise checks.

interface Config { timeout: number; retries: number; }
const config: Config = {
  timeout: 3000,
  retries: 3,
  // extra: true // Error: excess property
};

Contextual Typing in JSX

In React, event handler props are contextually typed so event parameter types are inferred automatically.

function Button({ onClick }: { onClick: (e: React.MouseEvent) => void }) {
  return <button onClick={onClick}>Click</button>;
}
// Caller: e is inferred as React.MouseEvent
<Button onClick={(e) => console.log(e.currentTarget)} />

Contextual Typing vs Explicit Annotations

Contextual typing is powerful but can be overridden by explicit annotations. Explicit beats contextual when both are present.

const handler: (x: string) => void = (x: number) => {}; // Error
// Explicit annotation (number) conflicts with contextual (string)

Contextual Typing with Destructuring

Destructured parameters in contextually typed functions also inherit their types from context.

const pairs: [string, number][] = [["a", 1]];
pairs.forEach(([key, value]) => {
  // key: string, value: number — contextually typed
  console.log(key.toUpperCase(), value * 2);
});

Contextual Typing and Return Types

When a function is assigned to a typed variable, the return type is also inferred contextually.

type Transform = (x: number) => string;
const double: Transform = (x) => x * 2; // Error: number not string
const str: Transform = (x) => String(x * 2); // OK

Contextual Typing in Conditional Expressions

TypeScript can propagate contextual types into ternary expressions and logical operators.

const result: string | null =
  Math.random() > 0.5 ? "yes" : null; // both arms typed by context

Limitations of Contextual Typing

Contextual typing does not apply when the expression is in a non-contextual position, such as a standalone variable without annotation.

const fn = (x) => x + 1; // x: any — no context to infer from
// Add annotation: const fn = (x: number) => x + 1;

Bidirectional Inference

TypeScript performs bidirectional type inference: both top-down (contextual) and bottom-up (from the expression). They cooperate to give you the most accurate type.

function apply<T>(fn: (x: T) => T, val: T): T { return fn(val); }
apply((x) => x.toUpperCase(), "hello"); // x inferred as string

Recap: Contextual Typing

Contextual typing lets TypeScript infer types from the position an expression is used in — callbacks, assignments, JSX props, and destructuring all benefit from this inference mechanism.

Quick Check

When does contextual typing apply to a callback parameter?

What You Learned

Contextual typing is TypeScript inferring types from position rather than value. It makes callbacks, event handlers, and typed assignments concise while remaining type-safe.

Frequently asked questions

Is the “Contextual Typing: Inference from Context” lesson free?

Yes — the full text of “Contextual Typing: Inference from Context” is free to read here on the web, and the TypeScript Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.

What will I learn in “Contextual Typing: Inference from Context”?

Understand how TypeScript infers types from surrounding context. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start TypeScript Academy?

No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Contextual Typing: Inference from Context” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this TypeScript Academy lesson?

Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Type Widening and Narrowing Mechanics
  2. Contextual Typing: Inference from Context
  3. Freshness and Excess Property Checking
  4. const Assertions and as const
← Back to TypeScript Academy