TypeScript Basics

Types & Inference

TypeScript is JavaScript with a static type system layered on top. It catches bugs at compile time, then erases entirely — the code that runs is plain JavaScript.

TypeScript 5 ✓ Beginner Friendly 2 Topics
01

Type Annotations & Inference

You annotate a variable's type with : type. But most of the time you don't have to — TypeScript infers the type from the value. The compiler then rejects any assignment that violates it.

TypeScript — Annotations & Inference
// explicit annotation
let age: number = 25;
let name: string = "Alice";
let active: boolean = true;

// inference — TS deduces the type, no annotation needed
let count = 10;          // inferred: number
let title = "hi";        // inferred: string

// the compiler now enforces it
count = 20;               // OK
// count = "twenty";      // Error: Type 'string' is not assignable to 'number'

// arrays and objects
let nums: number[] = [1, 2, 3];
let user: { name: string; age: number } = { name: "Ada", age: 36 };
Annotate or Infer?
✓ Let TS infer
  • Local variables with an initializer
  • Return types the compiler can see
  • Array/object literals
✎ Annotate explicitly
  • Function parameters (always)
  • Public API boundaries
  • Empty [] or {} you'll fill later
Types are erased at compile time. TypeScript compiles to plain JavaScript with all annotations stripped out. There is no runtime type checking — a : number does not stop a bad value arriving from an untyped API. Types are a compile-time contract, not a runtime guard.
02

any, unknown & never

Three special types define the edges of the type system. Knowing when to use each — and when not to reach for any — is a core TypeScript skill.

TypeMeansUse For
anyDisables type checkingEscape hatch — avoid; defeats the purpose
unknownAny value, but must be narrowed before useSafe alternative to any for untyped input
neverA value that never occursExhaustiveness checks, functions that always throw
voidNo return valueFunctions that return nothing
null / undefinedAbsence of a valueHandled by strictNullChecks
TypeScript — unknown vs any
// any — anything goes, no safety (avoid)
let a: any = "hello";
a.toFixed();           // no error at compile time, CRASHES at runtime

// unknown — safe: must narrow before you can use it
let u: unknown = getInput();
// u.toFixed();          // Error: 'u' is of type 'unknown'
if (typeof u === "number") {
  u.toFixed();         // OK — narrowed to number here
}

// never — the empty type; used for exhaustiveness
function fail(msg: string): never {
  throw new Error(msg);   // never returns normally
}
Prefer unknown over any for values of uncertain type (API responses, JSON.parse). unknown forces you to check the type before use; any silently turns off all safety and lets runtime crashes through.

Quick Quiz

1. What happens to type annotations at runtime?
2. For an untyped API response, the safest type is…
3. let count = 10; infers count as…
4. A function that always throws has return type…
5. Where should you always annotate types?