TypeScript · Types that pay for themselves

How does type inference work in TypeScript?

Easyinferencewideningtype-systemUpdated Oct 2026
Quiz this track

Short answer

TypeScript infers types from initializers, return values and context, so many annotations are unnecessary. Inference widens literals for mutable bindings but keeps them narrow for const.

The compiler uses the value on the right of a declaration to infer the type on the left. Function return types are inferred from the returned expressions. Parameters are also inferred from the arguments at a call site, and object literals can be checked against an expected type through contextual typing.

ts
const name = "Asha";
let count = 0;
const ids = [1, 2, 3];

function double(value: number) {
  return value * 2;
}

const doubled = double(21);
name is "Asha", count is number, ids is number[], and double returns number without an explicit annotation.

Widening and const

  • A mutable binding widens a literal, so let status = "idle" becomes string
  • A const binding keeps the literal type, so const status = "idle" is "idle"
  • Object properties widen unless the object is marked as const
  • Contextual typing flows from a parameter, variable or return type into an expression
ts
const config = {
  mode: "dark",
  retries: 3,
} as const;

type Mode = typeof config.mode;
Without as const, mode would be inferred as string instead of the literal "dark".

Inference is usually better than annotating every local variable. Annotations are most valuable on exported functions, public class members and places where the inferred type would be too wide or too confusing. Letting the compiler infer internals keeps the code shorter and avoids duplicate type information.

If a function's return type is part of a public contract, annotate it. Inference can silently widen a return type when the implementation changes.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1Why does a const keep a literal type while let widens it?
  2. 2What is contextual typing?
  3. 3When should you annotate a return type?
  4. 4How does as const change inference?

Say it in the interview

TypeScript infers types from initializers, return statements and context, so most local variables do not need annotations. A mutable binding widens a literal to its general type, while a const keeps the literal. I annotate public function signatures and module boundaries where inference is less useful to callers, and I let locals stay inferred.

Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.

Related questions

Reading is step one

Now say it out loud.

Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live TypeScript mock interview and get scored feedback on depth, clarity and confidence.