How to Convert JavaScript to TypeScript

A practical step-by-step guide to migrating any JavaScript project to TypeScript — including React apps, Node.js backends, and libraries.

TypeScript is a superset of JavaScript, so migration is gradual — you don't need to convert everything at once. This guide walks through each step in order, from setup to full strict mode.

1

Install TypeScript

Add TypeScript as a dev dependency:

npm install --save-dev typescript
# or
yarn add -D typescript

Generate a tsconfig.json:

npx tsc --init
2

Configure tsconfig.json for Gradual Migration

Start permissive — allow JavaScript files and don't enforce strictness yet:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "allowJs": true,          // allow .js files alongside .ts
    "checkJs": false,         // don't type-check .js files yet
    "strict": false,          // enable after migration is complete
    "outDir": "./dist",
    "rootDir": "./src",
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["src"]
}
3

Rename Files One at a Time

Rename .js → .ts and .jsx → .tsx. Start with files that have the fewest dependencies:

# Rename utility files first (no JSX)
mv src/utils/formatDate.js src/utils/formatDate.ts
mv src/utils/api.js src/utils/api.ts

# Then React components
mv src/components/Button.jsx src/components/Button.tsx
mv src/components/Header.jsx src/components/Header.tsx

# Pages last (depend on everything else)
mv src/pages/Home.jsx src/pages/Home.tsx
4

Add Types to Functions and Variables

Fix TypeScript errors by annotating function parameters and return types:

Before (JavaScript)

function formatDate(date) {
  return date.toLocaleDateString();
}

function fetchUser(id) {
  return fetch('/api/users/' + id)
    .then(r => r.json());
}

After (TypeScript)

function formatDate(date: Date): string {
  return date.toLocaleDateString();
}

async function fetchUser(id: number): Promise<User> {
  const res = await fetch('/api/users/' + id);
  return res.json() as User;
}
5

Type React Component Props

Define interfaces for component props and state:

Before (JSX)

function UserCard({ name, email, avatar }) {
  return (
    <div>
      <img src={avatar} alt={name} />
      <h2>{name}</h2>
      <p>{email}</p>
    </div>
  );
}

After (TSX)

interface UserCardProps {
  name: string;
  email: string;
  avatar: string;
}

function UserCard({ name, email, avatar }: UserCardProps) {
  return (
    <div>
      <img src={avatar} alt={name} />
      <h2>{name}</h2>
      <p>{email}</p>
    </div>
  );
}
6

Install Type Definitions for Libraries

Many npm packages need separate @types packages for TypeScript:

npm install --save-dev @types/node
npm install --save-dev @types/react @types/react-dom
npm install --save-dev @types/lodash

# Check if a package has types:
# 1. Built-in: look for "types" in package.json
# 2. DefinitelyTyped: npm install @types/<package-name>
# 3. TypeScript-first packages include types (axios, zod, etc.)
7

Enable Strict Mode

Once all files are converted, turn on strict mode to catch null/undefined bugs:

{
  "compilerOptions": {
    "strict": true,
    // strict enables all of:
    // strictNullChecks — catches null/undefined errors
    // noImplicitAny — no untyped variables
    // strictFunctionTypes
    // strictPropertyInitialization
    // useUnknownInCatchVariables
  }
}

Expect new errors. Fix them by adding null checks and non-null assertions where appropriate.

8

Automate with an AI Tool

For large files, use an AI converter to add types automatically instead of writing them by hand:

Tip: Use js2ts.com to convert JavaScript files automatically

Paste any JavaScript function, class, or component and get the TypeScript equivalent with types added instantly. Review and adjust the output.

Convert JavaScript to TypeScript automatically with AI

Use the JS to TS Converter →