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
let age = 30;
let name = "Sam";
function greet(name) {
return "Hi " + name;
}
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
: stringafter 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.
let age: number = 30;
let isAdult: boolean = age >= 18;
let label: string = `Age: ${age}`;
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.
function greet(name: string): string {
return "Hi " + name;
}
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.