Basic Types, Inference and Annotations
BeginnerAnnotate function boundaries and let inference handle the rest. Over-annotating is a common beginner habit that makes code noisier without making it safer.
Overview
TypeScript infers far more than people coming from Java expect. Declaring `const x: number = 5` adds nothing — the compiler already knew. The rule that works in practice is to annotate the boundaries where inference cannot reach or where you want the compiler to hold you to a contract: function parameters, exported return types, and empty containers. Everything in between should be inferred, because inferred types stay correct when the code changes and hand-written ones drift.
The Primitives
Lowercase names for primitives. The capitalised ones are wrapper objects and you almost never want them.
let name: string = 'Akshay'
let count: number = 42 // one number type — no int/long/float
let big: bigint = 9007199254740993n
let ok: boolean = true
let nothing: null = null
let missing: undefined = undefined
let key: symbol = Symbol('id')
// Arrays and tuples
let scores: number[] = [90, 85]
let pair: [string, number] = ['arrays', 12] // fixed length and order
let named: [x: number, y: number] = [1, 2] // labels, for readability
// any switches off checking; unknown keeps it on
let a: any = getValue()
a.whatever.deeply.nested // compiles, may explode
let u: unknown = getValue()
u.whatever // Error — must narrow first
if (typeof u === 'string') u.toUpperCase() // now allowed
// never — the type with no values; the return type of a function that throws
function fail(msg: string): never { throw new Error(msg) }Inference vs Annotation
Where to annotate and where not to.
// Redundant — inference already got it
const count: number = 0
const names: string[] = ['a', 'b']
// Just write
const count = 0 // number
const names = ['a', 'b'] // string[]
// DO annotate: parameters, and exported return types
export function score(attempts: Attempt[], weight: number): Readiness {
...
}
// The return annotation makes the compiler check the body against the
// contract, so a mistake is reported here rather than at every call site.
// DO annotate: empty containers, which infer as never[] or {}
const seen: string[] = []
const cache: Record<string, User> = {}
// let vs const widening
const dir = 'up' // type is 'up' — the literal
let dir2 = 'up' // type is string — widened
// which is why const works where a literal type is requiredFunctions
Optional parameters, defaults, rest, and typing a function value.
function paginate(page: number, size = 20, sort?: string) {
// size is number (inferred from the default)
// sort is string | undefined
}
function sum(...nums: number[]): number {
return nums.reduce((a, b) => a + b, 0)
}
// Typing a variable that holds a function
type Comparator = (a: Problem, b: Problem) => number
const byDifficulty: Comparator = (a, b) => a.level - b.level
// Parameters need no annotation — they are inferred from Comparator.
// This is "contextual typing" and it is why callbacks rarely need types.
items.filter((item) => item.active) // item inferred from items
// void return means "ignore whatever this returns"
type Handler = (e: Event) => void
const h: Handler = (e) => true // allowed; the boolean is discardedKey Points to Remember
- 1TypeScript has one number type — no int, long, float or double distinction
- 2Annotate function parameters and exported return types; let everything else infer
- 3any disables checking entirely; unknown forces you to narrow before use and is the safe alternative
- 4const infers a literal type while let widens to the primitive, which matters for unions
- 5Callback parameters are contextually typed from the surrounding signature, so they rarely need annotations
Interview Questions
Sign in to ask AriaWhat is the difference between any and unknown?
Why does const x = "up" have a different type than let x = "up"?
When is it worth annotating a function's return type rather than letting it infer?
Ask Aria about Basic Types, Inference and Annotations
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.