TypeScript Basics

TypeScript adds static types to JavaScript, catching errors at compile time and dramatically improving the editor experience (autocomplete, inline docs, safe refactoring). Because it's a superset of JavaScript, you can adopt it gradually — rename a file, add a few types, and tighten over time.

This is the practical fundamentals reference: the types and constructs you'll use every day. For the powerful stuff (conditional/mapped types, narrowing tricks), see TypeScript Advanced Features.

TL;DR

Quick Example

A typed function catches mistakes the editor flags before you run anything:

Getting Started

Basic Types

Interfaces & Type Aliases

Interface vs type: use interface for object shapes (extendable, mergeable, clearer errors); use type for unions, intersections, tuples, and primitives. Pick a convention and stay consistent.

Functions

Generics

Write reusable, type-safe code that works over any type:

Classes

Access modifiers: public (default), private, protected, and readonly.

Type Guards & Narrowing

Utility Types

Enums & Modules

💡 Many teams prefer string-literal unions (type Status = "pending" | "approved") over enum — they're simpler, have no runtime cost, and narrow cleanly.

Best Practices

Common Mistakes

Reaching for any

Overusing the non-null assertion

FAQ

How do I adopt TypeScript in an existing project?

Gradually. Add TypeScript, allow JS files (allowJs), and rename files to .ts/.tsx one at a time, adding types as you go. Start with looser settings and progressively enable strict checks. Because TS is a superset, valid JS is valid TS to begin with.

Interface or type alias?

Use interface for object shapes — it's extendable, supports declaration merging, and gives clearer errors. Use type for unions, intersections, tuples, and primitive aliases. They overlap a lot; consistency matters more than the choice.

What's the difference between any and unknown?

any disables type checking entirely — anything goes, and errors slip through. unknown is the type-safe counterpart: you can hold any value but must narrow it (with typeof, a guard, etc.) before using it. Prefer unknown for untyped input.

Do TypeScript types exist at runtime?

No — types are erased during compilation, leaving plain JavaScript. That's why a value as User assertion isn't a runtime check, and why you must validate external input (API responses, forms) with a runtime schema library.

Should I use enums?

You can, but many teams prefer string-literal unions ("a" | "b") — they're simpler, have zero runtime footprint, and narrow well. Reserve enum for cases where you specifically want a named runtime object, and consider const enum to avoid generated code.

Related Topics

References