What is type inference in TypeScript, and when should you still write type annotations?
Inference means the compiler works out a type from the value you assign, so you do not write it. Annotate function parameters, public return types and variables declared without a value, where inference has nothing to go on or where you want a contract.
Explain it simply
When you write const fare = 450, TypeScript already knows fare is a number, the way a conductor knows a ticket is Sleeper class just by reading it. Writing : number as well adds nothing.
Inference stops being useful where there is nothing to read. A function parameter has no value yet, so the compiler falls back to any (an error under strict). A variable declared empty, like let name;, is also too vague.
A good habit: let inference handle local variables, and annotate the boundaries of your code: parameters, exported function return types, and object shapes that other files depend on.
Example
const fare = 450; // inferred: 450 (literal, since const)
let seats = 3; // inferred: number
const stations = ["Pune", "Nashik"]; // inferred: string[]
function total(price: number, qty: number) { // params need annotations
return price * qty; // return inferred as number
}
// Explicit return type makes the contract visible and catches mistakes
function label(price: number): string {
// return price; // Error: number is not assignable to string
return `Rs ${price}`;
}What to say in the interview
"TypeScript infers types from initial values and from return statements, so I skip annotations on locals. I always annotate parameters, and I add explicit return types on exported functions so a wrong return is flagged inside the function, not at some distant caller."
Common mistakes
- Annotating every local variable, which adds noise without safety.
- Leaving a parameter unannotated and silently getting
anywhen noImplicitAny is off.