TypeScript · Types that pay for themselves
How does type inference work in TypeScript?
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.
const name = "Asha";
let count = 0;
const ids = [1, 2, 3];
function double(value: number) {
return value * 2;
}
const doubled = double(21);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
const config = {
mode: "dark",
retries: 3,
} as const;
type Mode = typeof config.mode;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.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1Why does a const keep a literal type while let widens it?
- 2What is contextual typing?
- 3When should you annotate a return type?
- 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.