Why TypeScript? JS vs TS

Difficulty: Beginner

Question

Why would you choose TypeScript over JavaScript? What problems does TypeScript solve?

Answer

TypeScript is a statically typed superset of JavaScript that compiles to plain JS. It solves several major pain points in JavaScript development:

1. Catches bugs at compile time instead of runtime - typos, wrong argument types, missing properties are all caught before your code ever runs.

2. Self-documenting code - type annotations serve as living documentation. Function signatures tell you exactly what inputs are expected and what output is returned.

3. Superior IDE support - autocompletion, refactoring, go-to-definition, and inline errors are dramatically better with types.

4. Safer refactoring - when you change a type or interface, the compiler immediately shows every place that needs updating.

5. Gradual adoption - since TS is a superset of JS, you can adopt it incrementally. Any valid JS is valid TS.

Code examples

Bugs Caught at Compile Time

// JavaScript - these bugs only show up at runtime
function getUser(id) {
  return fetch('/api/users/' + id);
}
getUser(); // No error in JS, but fails at runtime!

// TypeScript - caught immediately
function getUser(id: number): Promise<User> {
  return fetch('/api/users/' + id).then(r => r.json());
}
getUser();        // Error: Expected 1 argument, got 0
getUser('abc');   // Error: Argument of type 'string' not assignable to 'number'
getUser(123);     // OK

// Property access safety
interface User {
  name: string;
  email: string;
}
const user: User = { name: 'Alice', email: 'a@b.com' };
console.log(user.nme); // Error: Property 'nme' does not exist. Did you mean 'name'?

TypeScript catches entire categories of bugs that JavaScript would only reveal at runtime, including typos, wrong types, and missing arguments.

Self-Documenting Function Signatures

// JavaScript - what does this function expect? Who knows.
function processOrder(order, options) {
  // ... you'd have to read the implementation
}

// TypeScript - crystal clear contract
interface Order {
  id: string;
  items: { productId: string; quantity: number; price: number }[];
  customerId: string;
  status: 'pending' | 'confirmed' | 'shipped' | 'delivered';
}

interface ProcessOptions {
  sendEmail?: boolean;
  validateInventory?: boolean;
  applyDiscount?: string;
}

function processOrder(order: Order, options: ProcessOptions = {}): Promise<Order> {
  // The signature IS the documentation
}

// Callers know exactly what to pass
processOrder(
  { id: '1', items: [], customerId: 'c1', status: 'pending' },
  { sendEmail: true }
);

Type annotations serve as always-up-to-date documentation. Unlike JSDoc comments, types are enforced by the compiler and cannot become stale.

Safe Refactoring

// Before: User has 'name' field
interface User {
  id: number;
  name: string;
  email: string;
}

// After refactoring: split into firstName + lastName
interface User {
  id: number;
  firstName: string;
  lastName: string;
  email: string;
}

// TypeScript immediately flags EVERY place that used 'name'
// File: components/UserCard.tsx
//   Error: Property 'name' does not exist on type 'User'
// File: utils/formatUser.ts
//   Error: Property 'name' does not exist on type 'User'
// File: api/createUser.ts
//   Error: 'name' does not exist in type 'User'

// In JavaScript, these would be silent bugs discovered by users

When you change a type, the compiler creates a checklist of every file that needs updating. This makes large refactors safe and complete.

Key points

Concepts covered

TypeScript Benefits, Static Typing, JavaScript Comparison, Type Safety, Developer Experience