Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Type Inference  ›  Lesson

How Type Inference Works

Type Inference 12 minTypeScript works out a type from the value you assign or return, so you only need annotations where it cannot see a value, such as function parameters.

How Type Inference Works

New TypeScript users often annotate everything: let count: number = 0, const title: string = "Buy milk". It works, but it is noise. The compiler can already see those types. Knowing what it infers tells you exactly where annotations earn their place.

The rule

Where there is a value, TypeScript infers; where there is none, you annotate.

Inference means the compiler works out a type from the code around it.

let count = 0;            // number
const status = "open";    // "open" (a literal type)
let tags = ["home", 1];   // (string | number)[]

function makeTask(title: string) {
  return { title, done: false };
}
// return type inferred: { title: string; done: boolean }

Notice the difference between let and const. A let variable can be reassigned, so TypeScript widens 0 to the general type number. A const can never change, so it keeps the exact literal type "open". For an array of mixed values it infers an array of a union — "each element is a string or a number".

Inference also flows into callbacks. This is called contextual typing:

const ids = [3, 1, 2];
ids.map(n => n * 2); // n is number, because ids is number[]

The place inference cannot help is a function parameter with no default value. Nothing in the function tells TypeScript what callers will pass, so title would silently become any. With the noImplicitAny check (part of strict mode) that is an error, which is why parameters are the main thing you annotate.

The shortcut

Scan a line and ask "Can the compiler see a value here?"

  • A variable with an initial value → it can see one. Skip the annotation.
  • A function's return → it can see the return statements. Annotation optional.
  • A parameter, or a variable declared with no value → it cannot. Annotate.
Annotating a small task moduleStep 1 of 4
  1. let nextId = 1;

    Value visible, so nextId is inferred as number. No annotation needed.

A common surprise: let status = "open" has type string, not "open", so it will not fit a parameter that only accepts "open" | "closed". Use const or an annotation when you need the literal.

Drills

Answer fast — trust the rule.

quick drill

What type does TypeScript infer for let price = 9.5;?

quick drill

What type does TypeScript infer for const mode = "dark";?

quick drill

Where does TypeScript usually need you to write a type annotation?

quick drill

In ["a", "b"].map(s => s.length), what is the type of s?

quick drill

What does TypeScript infer for let mixed = [1, "two"];?

Remember

  • Where there is a value, TypeScript infers; where there is none, you annotate.
  • let widens to number or string; const keeps the literal.
  • Trap: unannotated parameters become any — strict mode turns that into an error.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainAnnotate or let it infer?

Look at let count = 0; const status = "open"; function addTask(title) { return { title, done: false }; }. Explain what type TypeScript infers for each of count, status, the parameter title and the return value, and where you would add an annotation.