iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

TS Type Inference

TypeScript infers a type from how you use a value. You don't always have to write it down — the compiler watches and figures it out.

Simple inference

TS
let message = 'Hello';   // string
let count   = 5;          // number
let flags   = [true];     // boolean[]

// message = 42;          // ✗ error — string was inferred

const vs let

The compiler is smarter for const than for let — it can narrow to a literal type:

TS
const greeting = 'Hello';   // type: 'Hello' (literal)
let   greeting2 = 'Hello';   // type: string

Best common type

TS
const mixed = [1, 'two', 3];       // (string | number)[]
const codes = ['ok', 'fail'] as const;   // readonly ['ok', 'fail']

Contextual typing

When the surrounding context says what a value should be, TS uses it:

TS
const nums = [1, 2, 3];
nums.forEach(n => n.toFixed(2));   // n inferred as number — no annotation needed

window.addEventListener('click', e => {
    // e inferred as MouseEvent
    console.log(e.clientX);
});

When to annotate explicitly

AnnotateSkip
Function parameters & return typesLocal variables initialised immediately
Exported module-level constantsThe result of .map, .filter, …
Empty arrays / objects you'll mutateLoop indexes and accumulators
Class fields without an initialiserAnything obvious from one line above
Tip: Hover over a name in your editor — TS shows the inferred type. If it surprises you, that's a signal to add an annotation (or fix the value).

Example

Example
// No annotation needed — TS infers `string`.
let message = 'Hello';      // string
let count   = 5;            // number
let flags   = [true, false]; // boolean[]

// message = 42;            // would error
console.log(typeof message, typeof count);
Try it Yourself »

Exercise

Type of "const m = 'hi';" is…

Test yourself

Q1. For "const message = 'Hello';" the type is…
Q2. TypeScript infers from…
Q3. Should you annotate every local variable?

Discussion

Loading…