Getting Started with TypeScript: A Practical Guide
TypeScript adds a safety net to JavaScript without slowing you down. Here's how to set it up, the handful of concepts that matter, and how to adopt it gradually.
TypeScript is JavaScript with types. You write almost the same code, add a few annotations, and the compiler catches a whole class of bugs before your code ever runs. Here’s the practical path to using it.
Why bother
Most runtime errors in JavaScript come down to a value not being what you assumed — undefined where you expected an object, a string where you expected a number. TypeScript surfaces those mistakes in your editor as you type, and it powers the autocomplete that makes large codebases navigable.
Setting it up
In any Node project:
npm install -D typescript
npx tsc --init
tsc --init creates a tsconfig.json. The one setting worth turning on immediately is strict:
{
"compilerOptions": {
"strict": true,
"target": "ES2022",
"module": "ESNext"
}
}
Strict mode is where TypeScript earns its keep — it forces you to handle the null/undefined cases that cause most crashes.
The concepts that matter
Basic annotations
let count: number = 0;
function greet(name: string): string {
return `Hello, ${name}`;
}
In practice you rarely annotate variables — TypeScript infers them. You mostly annotate function parameters and object shapes.
Interfaces and types
Describe the shape of your data once and reuse it everywhere:
interface User {
id: number;
name: string;
email?: string; // optional
}
Unions
A value that can be one of several types:
type Status = "loading" | "success" | "error";
Unions plus strict mode give you exhaustive checks — the compiler warns you if you forget to handle a case.
Adopt it gradually
You don’t have to convert everything at once. TypeScript runs on plain JavaScript, so you can:
- Rename one file from
.jsto.ts. - Fix the errors it surfaces.
- Repeat.
Set "allowJs": true so typed and untyped files coexist while you migrate.
Type narrowing: the everyday superpower
TypeScript follows your control flow. Inside an if that checks a value, the type is automatically narrowed:
function format(value: string | number) {
if (typeof value === "number") {
return value.toFixed(2); // value is `number` here
}
return value.trim(); // value is `string` here
}
This is why unions feel effortless in practice — you rarely cast types by hand; you check them, and the compiler narrows for you.
Common beginner mistakes
- Reaching for
any.anyswitches off type checking for that value and quietly spreads. Preferunknownand narrow it, or write the real type. - Over-annotating. Let inference do its job. Annotate function parameters and public APIs; leave local variables alone.
- Fighting third-party types. Most popular packages ship types or have a
@types/<name>package. Install those instead of declaring your own. - Ignoring
strictNullChecks. It’s the single most valuable check — leaving it off throws away most of TypeScript’s safety.
Frequently asked questions
Do I need to compile TypeScript myself?
Usually not. Bundlers and frameworks (Vite, Astro, Next.js) handle it. tsc is mainly for type-checking in CI and building libraries.
Is TypeScript slower at runtime? No. Types are erased during compilation — the JavaScript that ships is the same. The cost is at build time, not in the browser.
Should a brand-new project start with TypeScript? For anything beyond a throwaway script, yes. Adding types later is more work than starting with them.
The takeaway
Turn on strict, annotate your function boundaries, and let inference handle the rest. Within a week the editor feedback alone will make it hard to go back.
Keep reading
Understanding the JavaScript Event Loop
Why does JavaScript feel single-threaded yet handle so much at once? The event loop is the answer. Here's a clear mental model with examples you can run.
HTTPS Explained: What Happens When You Visit a Site
The padlock in your address bar hides a clever handshake. Here's what actually happens when you load an HTTPS site — encryption, certificates, and trust.
CSS Grid vs. Flexbox: When to Use Each
Grid and Flexbox aren't rivals — they solve different problems. A simple rule of thumb, with examples, for choosing the right layout tool every time.