Skip to main content

Assigning Types And Type Inference

Two ways a variable gets a type

1. You annotate it explicitly with : type:

let score: number = 10;
let name: string = "Ajay";
let active: boolean = true;

2. TypeScript infers it from the value you assign — no annotation needed:

let score = 10;       // inferred as number
let name = "Ajay"; // inferred as string
score = "ten"; // Error — it's still number, inference isn't "anything goes"

Prefer inference — annotate only when it adds value

If the value makes the type obvious, let TypeScript infer it. Redundant annotations are noise. Reach for an explicit type when there is no initial value, or when you want to constrain something wider than the literal.

let total = 0;          // Valid: inferred number — no annotation needed
let user: User; // Valid: annotate — no value yet to infer from
let id: string | number = 1; // Valid: annotate — you want a wider type than `number`

let vs const changes the inferred type

A subtle but important detail: const infers the literal type, let infers the widened type.

let a = "hello";    // type: string   (can be reassigned to any string)
const b = "hello"; // type: "hello" (literal — it can never change)

Inference is not "give me any." TypeScript picks the most specific type it safely can, then holds you to it. Fighting inference with needless annotations usually means you're working against the compiler, not with it.