TypeScript #
JavaScript is an incredibly flexible language — and that flexibility is a double-edged sword. On one hand, you can write code quickly without much ceremony. On the other, in codebases that grow large and are worked on by many people, that flexibility turns into a source of hard-to-trace bugs: functions that accept arbitrary data types, undefined object properties, undefined is not a function appearing in production. TypeScript was born from real frustration with this problem. Developed by Microsoft and released to the public in 2012, TypeScript is a superset of JavaScript that adds a static type system — without throwing away a single line of the existing JavaScript ecosystem. You still write JavaScript, but with a layer of type safety that lets IDEs and the compiler detect bugs before the program runs.
What Is TypeScript? #
TypeScript isn’t a standalone language. It’s a superset of JavaScript — meaning every valid JavaScript code is also valid TypeScript code. You can take any .js file, change its extension to .ts, and the TypeScript compiler will accept it without complaint (though without the full benefits of type checking).
What TypeScript adds on top of JavaScript is a static type system — the ability to explicitly declare the types of variables, function parameters, and return values, so the TypeScript compiler (tsc) can verify the correctness of type usage across the codebase before the code runs.
// JavaScript: no type information
function hitungHarga(harga, jumlah, diskon) {
return harga * jumlah * (1 - diskon);
}
// Is diskon in the form 0.1 or 10 (percent)?
// Can jumlah be a string? Nobody knows without reading the implementation.
hitungHarga("15000", 2, 10); // no error, but the result is wrong
// TypeScript: an explicit function contract
function hitungHargaTS(
harga: number,
jumlah: number,
diskon: number // 0.0 – 1.0
): number {
return harga * jumlah * (1 - diskon);
}
hitungHargaTS("15000", 2, 0.1);
// Error: Argument of type 'string' is not assignable to parameter of type 'number'
// ↑ Caught by the compiler, not in production
It’s important to understand: TypeScript doesn’t exist at runtime. Before the program runs, the TypeScript compiler transforms .ts code into plain JavaScript. Browsers, Node.js, and Deno know nothing about TypeScript — they only run the compiled JavaScript. This means adopting TypeScript doesn’t require any changes to your deployment environment.
flowchart LR
A["TypeScript Code\n(.ts / .tsx)"] -->|tsc| B["JavaScript\n(.js)"]
B -->|runs in| C["Browser"]
B -->|runs in| D["Node.js"]
B -->|runs in| E["Deno / Bun"]
A -->|type checking| F["Type errors\ndetected before runtime"]Why TypeScript Exists — The Problems It Solves #
To truly appreciate TypeScript, you need to feel the problems it solves. JavaScript was designed in 1995 for small scripts in the browser — not for applications with hundreds of thousands of lines worked on by dozens of developers. As JavaScript became a server language (Node.js) and an enterprise application language (Angular, React, Vue at scale), its limitations began to hurt.
Problem 1: No Contracts Between Modules #
In pure JavaScript, you can’t tell from a function signature what it expects and what it returns without reading the entire implementation — or hoping the documentation is up to date.
// ANTI-PATTERN (JavaScript): a signature without a contract
function simpanUser(user) {
// is user.id required?
// can user.email be undefined?
// does this function return anything?
db.save(user);
}
// CORRECT (TypeScript): an explicit contract
interface User {
id: number;
nama: string;
email: string;
telepon?: string; // ? = optional
}
function simpanUser(user: User): Promise<void> {
return db.save(user);
}
Problem 2: Dangerous Refactoring #
In JavaScript, renaming a property or changing an object’s structure is a dangerous operation — you don’t know all the places that property is used without running a full test suite (or waiting for bug reports from users). TypeScript makes refactoring safe: rename a property in one place, and all the usages that weren’t updated turn red in the editor immediately.
Problem 3: Inaccurate Autocomplete #
Without type information, IDEs can’t provide accurate autocomplete for object properties or function parameters. TypeScript enables precise IntelliSense — not just guessing based on usage, but based on explicit type definitions.
flowchart TD
A["JavaScript Problems\nat Scale"] --> B["No contracts\nbetween modules"]
A --> C["Dangerous\nrefactoring"]
A --> D["Inaccurate\nautocomplete"]
A --> E["Type bugs\nfound at runtime"]
B --> F["TypeScript\nInterface & Type"]
C --> F
D --> F
E --> F
F --> G["Bugs detected\nat compile time"]
F --> H["Safe refactoring\nwith the IDE"]
F --> I["Precise\nIntelliSense"]History and Evolution #
TypeScript was first publicly announced by Microsoft in October 2012, with version 0.8. The key figure behind its development is Anders Hejlsberg — the architect of C# and Delphi, one of the most influential language designers in the industry. It’s no coincidence that TypeScript feels like a JavaScript version of C#: they share the same design philosophy around strong typing and OOP.
Microsoft’s motivation was very practical: their internal teams struggled to build large-scale web applications (including Bing and Visual Studio Online) using pure JavaScript. They needed a way to bring typed programming discipline into JavaScript without leaving its ecosystem.
flowchart TD
A["October 2012\nTypeScript 0.8\nReleased to the public"] --> B["2014\nTypeScript 1.0\nFirst stable release\nIncluded in Visual Studio"]
B --> C["2016\nTypeScript 2.0\nStrict null checks\nNon-nullable types"]
C --> D["2018\nTypeScript 3.0\nProject references\nTuple improvements"]
D --> E["2020\nTypeScript 4.0\nVariadic tuple types\nLabeled tuple elements"]
E --> F["2022\nTypeScript 4.9\nSatisfies operator\nAuto-accessor"]
F --> G["2023\nTypeScript 5.0\nDecorators (standard)\nConst type parameters"]
G --> H["2024–2025\nTypeScript 5.x\nCompiler performance\nAdvanced type system features"]TypeScript’s popularity turning point happened around 2016–2017, triggered by two major events. First, Angular 2 (released in 2016) chose TypeScript as its main language — a decision that brought the entire Angular community to TypeScript. Second, React and its ecosystem started getting good TypeScript support through @types/react. From there, its growth never stopped.
The State of JS survey and the Stack Overflow Developer Survey consistently rank TypeScript as one of the most used and most loved languages by developers. By 2024, TypeScript had become the default in almost every modern frontend framework.
The TypeScript and JavaScript Relationship #
The relationship between TypeScript and JavaScript needs to be understood correctly because it’s often misunderstood.
TypeScript Is a Superset #
Every valid JavaScript file is valid TypeScript. You don’t need to rewrite your entire codebase to start using TypeScript — it can be done gradually, file by file.
JavaScript ⊂ TypeScript
(JavaScript is a subset of TypeScript)
TypeScript Compiles to JavaScript #
TypeScript has no runtime of its own. The compilation process (tsc) produces clean JavaScript that can run in any environment. Types disappear after compilation — there’s no runtime type checking unless you add it yourself with manual validation or a library like Zod.
// TypeScript source
interface Produk {
id: number;
nama: string;
harga: number;
}
function formatHarga(produk: Produk): string {
return `${produk.nama}: Rp ${produk.harga.toLocaleString('id-ID')}`;
}
// Compiled JavaScript (all types gone)
function formatHarga(produk) {
return `${produk.nama}: Rp ${produk.harga.toLocaleString('id-ID')}`;
}
TypeScript Follows the ECMAScript Standard #
TypeScript always supports modern JavaScript features (ESNext) and compiles to older JavaScript versions according to the configured target. This means you can use async/await, optional chaining (?.), nullish coalescing (??), and other latest features — TypeScript handles the compatibility.
| JavaScript Feature | TypeScript Support |
|---|---|
async/await | ✓ Full, compiled to ES5/ES6 depending on the target |
Optional chaining ?. | ✓ Since TypeScript 3.7 |
Nullish coalescing ?? | ✓ Since TypeScript 3.7 |
Logical assignment ??=, &&= | ✓ Since TypeScript 4.0 |
Top-level await | ✓ Since TypeScript 3.8 (ES modules) |
| Decorators (standard) | ✓ Since TypeScript 5.0 |
using (Explicit Resource Management) | ✓ Since TypeScript 5.2 |
Key Characteristics #
Static Typing and Type Inference #
TypeScript supports two modes of type annotation: explicit (you write it) and inferred (TypeScript guesses it from context). Both work together.
// Explicit: you declare the type
let nama: string = "Budi";
let usia: number = 28;
// Inferred: TypeScript knows the type from the initial value
let kota = "Jakarta"; // TypeScript: kota is a string
let aktif = true; // TypeScript: aktif is a boolean
let harga = 150_000; // TypeScript: harga is a number
// ANTI-PATTERN: redundant explicit annotations
let pesan: string = "halo"; // not needed, TypeScript already knows this is a string
// CORRECT: explicit annotations only when inference isn't enough
let hasil: string | number; // a union type that can't be inferred from the declaration
hasil = "sukses";
hasil = 0;
A Rich Type System #
TypeScript has a far more expressive type system than other statically typed languages like Java. Features like union types, intersection types, mapped types, conditional types, and template literal types let you model data with high precision.
// Union type: a value can be one of several types
type StatusPesanan = "menunggu" | "diproses" | "dikirim" | "selesai" | "dibatalkan";
// Intersection type: a combination of several types
type AdminUser = User & { level: "admin"; izin: string[] };
// Mapped type: automatic transformation from another type
type ReadOnly<T> = { readonly [K in keyof T]: T[K] };
// Template literal type: strings with a certain pattern
type EventName = `on${Capitalize<string>}`;
// Valid: "onClick", "onChange", "onSubmit"
Interface vs Type Alias #
Two ways to define the shape of an object in TypeScript, with important differences:
// Interface: can be extended and merged declaratively
interface Kendaraan {
merek: string;
tahun: number;
}
interface Kendaraan {
warna: string; // declaration merging: interfaces are merged automatically
}
interface Mobil extends Kendaraan {
jumlahPintu: number;
}
// Type alias: more flexible, works for unions/intersections
type ID = string | number;
type Koordinat = { lat: number; lng: number };
type Peta = Record<string, Koordinat>;
Generics #
Generics let you write components that work with various types while remaining type-safe — without code duplication.
// Without generics: must duplicate for every type
function ambilPertamaAngka(arr: number[]): number { return arr[0]; }
function ambilPertamaString(arr: string[]): string { return arr[0]; }
// With generics: one function for all types
function ambilPertama<T>(arr: T[]): T {
return arr[0];
}
const angka = ambilPertama([1, 2, 3]); // T = number
const kata = ambilPertama(["halo", "dunia"]); // T = string
// A generic with a constraint: T must have an id property
function cariById<T extends { id: number }>(items: T[], id: number): T | undefined {
return items.find(item => item.id === id);
}
Where Is TypeScript Used? #
TypeScript now exists in almost every layer of modern web development, and keeps expanding into other domains.
Frontend Web #
This is TypeScript’s main habitat. All major frontend frameworks now use or strongly support TypeScript:
| Framework | TypeScript Status |
|---|---|
| Angular | Written entirely in TypeScript since Angular 2 (2016), mandatory |
| React | Full support via @types/react, highly recommended for new projects |
| Vue 3 | Written in TypeScript, first-class type support |
| Svelte | TypeScript support via SvelteKit, increasingly mature |
| Next.js | TypeScript by default in new projects |
Backend with Node.js #
Node.js itself can’t run TypeScript directly, but its ecosystem strongly supports it:
// Example Express + TypeScript
import express, { Request, Response } from "express";
interface UserBody {
nama: string;
email: string;
}
const app = express();
app.use(express.json());
app.post("/users", (req: Request<{}, {}, UserBody>, res: Response) => {
const { nama, email } = req.body;
// req.body is already typed as UserBody — no guessing needed
res.json({ pesan: `User ${nama} berhasil dibuat`, email });
});
Backend frameworks built specifically for TypeScript are also growing in popularity: NestJS (an Angular-like architecture for the backend), tRPC (type-safe APIs without schemas), Elysia (for the Bun runtime).
Tooling and CLI #
Many modern developer tools are written in TypeScript: Vite, ESLint (the newer versions), Prisma, Drizzle ORM, Zod, and many more. This isn’t just a trend — TypeScript genuinely suits tooling because it makes maintaining complex codebases easier.
flowchart TD
TS["TypeScript\nin Industry"] --> FE["Frontend Web\nAngular, React, Vue\nNext.js, Svelte"]
TS --> BE["Backend\nNode.js + Express\nNestJS, tRPC, Elysia"]
TS --> Mobile["Mobile\nReact Native\nIonic, Capacitor"]
TS --> Tool["Tooling\nVite, ESLint, Prisma\nZod, Drizzle ORM"]
TS --> Full["Full-Stack\nT3 Stack\nNext.js + tRPC + Prisma"]Ecosystem and Tooling #
The TypeScript Compiler (tsc) #
tsc is the official TypeScript compiler. It reads the tsconfig.json file to determine the compilation target, strict mode, path aliases, and many other options.
# Install TypeScript
npm install -D typescript
# Create tsconfig.json
npx tsc --init
# Compile
npx tsc
# Watch mode: recompile when files change
npx tsc --watch
tsconfig.json — The Heart of Configuration #
tsconfig.json controls all TypeScript compiler behavior. Some of the most important options:
{
"compilerOptions": {
"target": "ES2022", // the output JavaScript version
"module": "ESNext", // the output module system
"strict": true, // enable all strict checks
"noUncheckedIndexedAccess": true, // array access is always | undefined
"exactOptionalPropertyTypes": true, // stricter optional properties
"outDir": "./dist", // the output directory
"rootDir": "./src", // the source directory
"paths": { // path aliases
"@/*": ["./src/*"]
}
}
}
Always enable"strict": truein new projects. Strict mode activates a set of checks that initially feel annoying but prevent the most common bug classes:strictNullCheckspreventsnull/undefinedfrom being accessed without checks,noImplicitAnyprevents unintentionalanytypes. Turning off strict mode is like using only half the benefits of TypeScript.
DefinitelyTyped and @types
#
JavaScript libraries that aren’t written in TypeScript have no type information. The community solved this problem through DefinitelyTyped — a repository of types for thousands of popular libraries, distributed as @types/* packages.
# Install a library + its types
npm install lodash
npm install -D @types/lodash
# Libraries written in TypeScript have built-in types
npm install axios # @types/axios not needed, axios already includes types
npm install zod # same, types are included
When to Choose TypeScript vs JavaScript #
Use TypeScript if:
✓ The project will grow large or is worked on by more than one person
✓ Need safe refactoring in the long term
✓ Using a TypeScript-first framework (Angular, NestJS, Next.js)
✓ Building a library or SDK that others will use
✓ The team has a background in statically typed languages (Java, C#, Go)
Consider JavaScript if:
✗ Small one-off scripts (build utilities, simple automation scripts)
✗ Very fast prototyping where iteration speed matters more than correctness
✗ The team is very unfamiliar with TypeScript and the deadline is very tight
✗ The runtime doesn't support it or TypeScript configuration is too complicated for the context
What You’ll Learn in This Documentation #
This documentation covers TypeScript from the foundations to real-world usage, with a focus on understanding the why rather than just the how.
flowchart TD
A["Basics\nInstallation & tsconfig\nVariables, Data Types\nFunctions, Classes, Interfaces\nGenerics, Exceptions"] --> B["Advanced\nAsync Programming\nI/O & Socket\nWeb Server\nUnit Test & Mocking"]
B --> C["Other Topics\nSQL & NoSQL Databases\nCache (Redis, Memcached)\nJSON & YAML\nArticles & Resources"]
C --> D["Standard Library\nStrings, IO, Math"]The Basics section builds a solid foundation: how to install TypeScript and configure tsconfig.json, basic syntax, the complete type system (primitives, unions, intersections, generics), classes and interfaces, exception handling, and List and Map data structures with proper types.
The Advanced section covers topics needed for real applications: asynchronous programming (Promises, async/await, the event loop), I/O operations, sockets and WebSockets, building web servers, and type-safe unit testing and mocking.
The Other Topics section is practical: integrating TypeScript with databases (MySQL, PostgreSQL, MSSQL, Oracle, MongoDB, Elasticsearch), caching (Redis, Memcached), data serialization (JSON, YAML), and reference articles.
The Standard Library section covers the utility modules often used for string manipulation, I/O operations, and mathematical functions.
Summary #
- TypeScript is a JavaScript superset — all valid JavaScript code is TypeScript. Adoption can be done gradually, file by file.
- TypeScript doesn’t exist at runtime — the compiler turns
.tsinto clean.js. Browsers and Node.js only see JavaScript. There’s no runtime overhead from TypeScript itself.- Static typing detects bugs at compile time — not at runtime or from user reports. This is TypeScript’s greatest advantage for large-scale codebases.
- Type inference reduces verbosity — TypeScript can often guess types from context. Write explicit type annotations only when inference isn’t enough.
- Always enable
strict: true— strict mode maximizes TypeScript’s benefits. Turning it off is like using half the language’s value.- Generics are the key to type-safe reusability — avoid code duplication for different types while maintaining type safety.
- The ecosystem is very mature —
@types/*provides types for thousands of JavaScript libraries, and modern frameworks are already TypeScript-first.- Anders Hejlsberg, the C# architect, designed TypeScript — the design philosophy is consistent: a productive language for developers and safe for large codebases.
Next: Installing TypeScript →