Lesson 1 of 5

Basic Types & Annotations

JavaScript never asks what a variable is going to hold — it just holds whatever you put in it, and happily lets you put something else in it five lines later. TypeScript is JavaScript with one thing bolted on top: a type checker that runs before your code ever executes, catching the "wait, that's not a number" bugs at write-time instead of at 2am in production.

💡 The Bottom Line

TypeScript adds optional type annotations to variables, function parameters, and return values, using a colon : after the name. Everything else about the language — the syntax, the runtime, the standard library — is still JavaScript. You write .ts files, and a compiler called tsc strips the types out and emits plain .js that runs anywhere JavaScript already runs.

The same variable, side by side

JavaScript
let age = 30;
let name = "Sam";

function greet(name) {
  return "Hi " + name;
}
TypeScript
let age: number = 30;
let name: string = "Sam";

function greet(name: string): string {
  return "Hi " + name;
}

📋 Key differences

  • A type annotation is a colon followed by a type name: age: number.
  • Function parameters get annotated the same way: (name: string).
  • The : string after the closing parenthesis annotates the return type of the function.
  • None of this exists at runtime — it's checked once, at compile time, then erased.

You don't need to annotate everything

New TypeScript developers often over-annotate out of habit, writing let age: number = 30; everywhere. TypeScript can usually figure the type out on its own from the value you assign — this is called type inference. If you write let age = 30; in a .ts file, TypeScript infers age is a number just as confidently as if you'd written it explicitly, and will still flag age = "thirty" a few lines later as an error.

Over-annotated
let age: number = 30;
let isAdult: boolean = age >= 18;
let label: string = `Age: ${age}`;
Idiomatic (inferred)
let age = 30;
let isAdult = age >= 18;
let label = `Age: ${age}`;

Annotations earn their keep in places TypeScript can't infer from context — most commonly, function parameters (TypeScript has no way to know what a caller will pass) and variables you declare before assigning them a value.

⚠️ Gotcha

Function parameters are the one place inference can't save you — TypeScript will not guess a parameter's type from how the function is used later. Leave a parameter unannotated with strict mode off, and it silently becomes any (a type that disables checking entirely — more on that in the last lesson), which quietly defeats the whole point of switching to TypeScript for that function.

The compile step: .ts becomes .js

Browsers and Node don't understand TypeScript — they only run JavaScript. TypeScript code goes through a compiler, tsc, that type-checks it and then emits an equivalent .js file with the annotations stripped out. In practice, most projects run this via a bundler (Vite, webpack) or a dev-time watcher rather than calling tsc by hand for every file, but the underlying step is always the same: check, then compile down to plain JS.

greet.ts
function greet(name: string): string {
  return "Hi " + name;
}
greet.js (compiled output)
function greet(name) {
  return "Hi " + name;
}

🔧 Try It Yourself

Install TypeScript locally (npm install -g typescript) or use the TypeScript Playground in your browser. Write a small function that takes two numbers and returns their sum, annotate the parameters as number and the return type as number, then try calling it with a string argument — watch the compiler catch the mistake before you ever run the code.

🙋 There Are No Dumb Questions

Q: If the types get erased at compile time, do they slow down or change my code at runtime?
A: No. Once tsc finishes checking your code, every annotation is deleted from the output — the compiled .js is exactly as fast as if you'd written it in plain JavaScript by hand, because at runtime, it is plain JavaScript. Types are a write-time and compile-time tool only.

✅ Quick Check

You write let total = 12; in a .ts file with no annotation. What does TypeScript do?


Next up: annotating individual variables is fine, but most real bugs come from objects with the wrong shape. That's where interface and type come in.

← Back to
Next →