All Articles
Tutorial8 min read

TypeScript for JavaScript Developers: Making the Switch

Ready to level up from JavaScript to TypeScript? Practical guide covering types, interfaces, generics, and gradual migration strategies.

T

TechGyanic

December 13, 2025

TypeScript for JavaScript Developers

After resisting TypeScript for two years, I finally made the switch. The catalyst? A production bug that would have been caught instantly with types. Here's how to transition without losing your mind.

Why TypeScript Matters Now

Most companies in India—from Swiggy to Zerodha—have moved their codebases to TypeScript. Job postings increasingly list it as required, not preferred.

Basic Types

// Primitive types
let name: string = "Rahul";
let age: number = 25;
let isActive: boolean = true;

// Arrays
let scores: number[] = [85, 90, 78];
let names: Array<string> = ["Amit", "Priya"];

// Objects
interface User {
  id: number;
  name: string;
  email: string;
  phone?: string; // Optional
}

const user: User = {
  id: 1,
  name: "Priya Sharma",
  email: "[email protected]"
};

Functions with Types

// Parameters and return type
function calculateTax(amount: number, rate: number = 0.18): number {
  return amount * rate;
}

// Arrow functions
const formatCurrency = (amount: number): string => {
  return `₹${amount.toLocaleString('en-IN')}`;
};

// Void return
function logMessage(message: string): void {
  console.log(message);
}

Interfaces vs Types

Both work, but here's when to use each:

// Interface - for object shapes, can extend
interface Product {
  id: number;
  name: string;
  price: number;
}

interface DigitalProduct extends Product {
  downloadUrl: string;
}

// Type - for unions, primitives, or tuples
type Status = "pending" | "completed" | "failed";
type Coordinates = [number, number];
type Handler = (event: Event) => void;

Generics

The concept that makes TypeScript powerful:

// Generic function
function getFirst<T>(array: T[]): T | undefined {
  return array[0];
}

const firstNumber = getFirst([1, 2, 3]); // type: number
const firstName = getFirst(["a", "b"]); // type: string

// Generic interface
interface ApiResponse<T> {
  data: T;
  status: number;
  message: string;
}

const userResponse: ApiResponse<User> = {
  data: { id: 1, name: "Test", email: "[email protected]" },
  status: 200,
  message: "Success"
};

Working with APIs

interface Post {
  id: number;
  title: string;
  content: string;
  authorId: number;
}

async function fetchPosts(): Promise<Post[]> {
  const response = await fetch("/api/posts");
  if (!response.ok) {
    throw new Error("Failed to fetch posts");
  }
  return response.json();
}

// Usage with error handling
try {
  const posts = await fetchPosts();
  posts.forEach(post => console.log(post.title));
} catch (error) {
  if (error instanceof Error) {
    console.error(error.message);
  }
}

Migrating an Existing Project

  1. Install TypeScript: npm install -D typescript @types/node
  2. Create tsconfig.json: npx tsc --init
  3. Rename files gradually: .js.ts, .jsx.tsx
  4. Fix errors file by file

Start with strict: false in tsconfig, then enable strict mode gradually:

{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true
  }
}

Common Pitfalls

  1. Any everywhere - Defeats the purpose. Use unknown for truly unknown types.
  2. Type assertions - as Type should be rare, not default.
  3. Ignoring compiler errors - Those red squiggles are catching bugs.

TypeScript has a learning curve, but after a month of consistent use, you'll wonder how you wrote JavaScript without it.

typescriptjavascriptfrontendprogrammingweb-development
Share this article
T

Written by

TechGyanic

Sharing insights on technology, software architecture, and development best practices.