Guides / TypeScript for JavaScript Developers

TypeScript for JavaScript Developers

6 min read · TypeScript

What TypeScript adds

TypeScript is JavaScript with static types. Every valid JavaScript file is already valid TypeScript — you can adopt it gradually. The TypeScript compiler checks your types at build time and then strips them out, producing plain JavaScript that runs anywhere.

The key benefit: TypeScript catches bugs before you run your code.

Basic type annotations

// JavaScript
function greet(name) {
  return "Hello, " + name;
}

// TypeScript
function greet(name: string): string {
  return "Hello, " + name;
}

// Types for variables
const age: number = 28;
const isActive: boolean = true;
const tags: string[] = ["admin", "editor"];

Type inference — TypeScript is smart

You do not need to annotate everything. TypeScript infers types from the values you assign:

const name = "Ana";      // TypeScript knows: string
const age = 28;          // TypeScript knows: number
const active = true;     // TypeScript knows: boolean

// TypeScript will warn you here:
age = "twenty-eight";    // Error: Type 'string' is not assignable to type 'number'

In practice, you only need to annotate function parameters and return types. The rest is inferred.

Interfaces and types

Use interface or type to describe the shape of an object:

interface User {
  id: number;
  name: string;
  email: string;
  role: "admin" | "editor" | "viewer";  // union type
  avatar?: string;  // optional property (string | undefined)
}

function displayUser(user: User): string {
  return `${user.name} (${user.role})`;
}

// TypeScript will catch this mistake:
displayUser({ id: 1, name: "Ana" });
// Error: Property 'email' is missing in type

Union types and type narrowing

A union type means a value can be one of several types:

type Status = "active" | "inactive" | "pending";

function getStatusLabel(status: Status): string {
  if (status === "active") return "Active";
  if (status === "inactive") return "Inactive";
  return "Pending";
}

// TypeScript catches impossible states:
getStatusLabel("deleted");  // Error: not in the union

Generics

Generics let you write reusable code that works with any type while remaining type-safe:

// A function that works with any type
function first<T>(arr: T[]): T | undefined {
  return arr[0];
}

const num = first([1, 2, 3]);     // TypeScript knows: number | undefined
const str = first(["a", "b"]);    // TypeScript knows: string | undefined

// Generic interface
interface ApiResponse<T> {
  data: T;
  error: string | null;
  status: number;
}

const response: ApiResponse<User[]> = {
  data: [...],
  error: null,
  status: 200,
};

TypeScript vs JavaScript: when to choose TypeScript

Choose TypeScript when...Stick with JavaScript when...
Building a large or long-lived codebaseWriting a small script or one-off tool
Working in a teamPrototyping or exploring an idea fast
Building a library or public APIA build step is not acceptable
Refactoring complex codeThe project will be thrown away

In 2025, TypeScript is the default choice for most production JavaScript projects. Most frameworks (Next.js, SvelteKit, NestJS, tRPC) have first-class TypeScript support.

Getting started

# Install TypeScript
npm install -D typescript

# Create a tsconfig.json
npx tsc --init

# Compile a file
npx tsc app.ts

# Watch mode (recompile on change)
npx tsc --watch

For new projects, use a framework starter that includes TypeScript by default —npx create-next-app or npm create vite@latest both offer TypeScript templates.

Format your TypeScript and JavaScript

Paste any TypeScript or JavaScript code and auto-format it with consistent style.