Menu
×
   ❮   
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS DSA TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI R GO KOTLIN SASS VUE GEN AI SCIPY CYBERSECURITY DATA SCIENCE INTRO TO PROGRAMMING BASH RUST

TypeScript Migration Guide


Migrating from JavaScript to TypeScript can significantly improve your codebase's maintainability and developer experience.

This guide will walk you through the process step by step.


Preparation Phase

Assess Your Codebase

Before starting the migration:

  • Identify the size and complexity of your codebase
  • Document the build process and dependencies
  • Check for any existing type definitions (.d.ts files)
  • Identify critical paths that need special attention

Set Up Version Control

Ensure you have a clean git repository or equivalent:

# Create a new branch for the migration
git checkout -b typescript-migration

# Commit your current state
git add .
git commit -m "Pre-TypeScript migration state"

Configuration

Install TypeScript

# Install TypeScript as a dev dependency
npm install --save-dev typescript @types/node

Create tsconfig.json

Create a basic tsconfig.json to start with:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist",
    "rootDir": "./src"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

Note: Adjust the target based on your minimum supported environments.


Migration Approaches

Gradual Migration

Migrate one file at a time while keeping the rest as JavaScript.

{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": true
  }
}

Best for: Large codebases, minimal disruption

All-at-Once Migration

Rename all .js files to .ts and fix errors.

# Rename all JS files to TS
find src -name "*.js" -exec sh -c 'mv "$0" "${0%.js}.ts"' {} \;

Best for: Small to medium projects, greenfield projects

Important Note

For large projects, we strongly recommend the gradual migration approach to minimize disruption and make the process more manageable.


Step-by-Step Migration

Start with Configuration

Create a basic tsconfig.json with these recommended settings:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "allowJs": true,
    "checkJs": true,
    "noEmit": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

Enable Type Checking for JavaScript

Add // @ts-check to the top of your JavaScript files to enable type checking:

// @ts-check

/** @type {string} */
const name = 'John';

// TypeScript will catch this error
name = 42; // Error: Type '42' is not assignable to type 'string'

Note: You can disable type checking for specific lines using // @ts-ignore.

Rename Files to .ts

Start with non-critical files and rename them from .js to .ts:

# Rename a single file
mv src/utils/helpers.js src/utils/helpers.ts

# Or rename all files in a directory (use with caution)
find src/utils -name "*.js" -exec sh -c 'mv "$0" "${0%.js}.ts"' {} \;

Add Type Annotations

Gradually add type annotations to your code:

// Before
function add(a, b) {
  return a + b;
}

// After
function add(a: number, b: number): number {
  return a + b;
}

// With interface
interface User {
  id: number;
  name: string;
  email?: string;
}

function getUser(id: number): User {
  return { id, name: 'John Doe' };
}

Update Build and Test Scripts

Modify your package.json to include TypeScript compilation:

{
  "scripts": {
    "build": "tsc",
    "dev": "tsc --watch",
    "test": "jest"
  }
}

Note: Make sure to update your test configuration to work with TypeScript files.


Migration Tools

ts-migrate

Automated tool for migrating JavaScript to TypeScript

npx ts-migrate-full .

GitHub Repository

TypeStat

Converts JavaScript to TypeScript with type safety

npx typestat --init

GitHub Repository

@types Packages

Install type definitions for your dependencies

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

TypeSearch


Best Practices for TypeScript Migration

Start Small and Iterate

  • Begin with utility functions and non-UI components
  • Migrate one file or module at a time
  • Commit after each successful migration step

Leverage TypeScript Features

// Use type inference where possible
const name = 'John'; // TypeScript infers 'string'
const age = 30; // TypeScript infers 'number'

// Use union types for flexibility
type Status = 'active' | 'inactive' | 'pending';

// Use type guards for runtime checks
function isString(value: any): value is string {
  return typeof value === 'string';
}

Handle Third-Party Libraries

  • Install @types packages for your dependencies
  • Create declaration files for libraries without types
  • Use declare module for global type extensions

Common Challenges and Solutions

Dynamic Properties

Problem: JavaScript often uses objects as dictionaries.

// Before
const user = {};
user.name = 'John'; // Error: Property 'name' does not exist

Solution: Use index signatures or type assertions.

// Option 1: Index signature
interface User {
  [key: string]: any;
}
const user: User = {};
user.name = 'John'; // OK

// Option 2: Type assertion
const user = {} as { name: string };
user.name = 'John'; // OK

Handling this Context

Problem: this binding issues in callbacks.

class Counter {
  count = 0;
  increment() {
    setTimeout(function() {
      this.count++; // Error: 'this' is not defined
    }, 1000);
  }
}

Solution: Use arrow functions or bind this.

// Solution 1: Arrow function
setTimeout(() => {
  this.count++; // 'this' is lexically scoped
}, 1000);

// Solution 2: Bind 'this'
setTimeout(function(this: Counter) {
  this.count++;
}.bind(this), 1000);

Conclusion

Migrating from JavaScript to TypeScript is a significant but rewarding investment in your codebase.

By following this guide, you can make the transition smoothly and incrementally.

Key Takeaways:

  • Start with a solid tsconfig.json configuration
  • Use allowJs and checkJs for gradual migration
  • Leverage TypeScript's type system to catch errors early
  • Update your build and test processes to support TypeScript
  • Address common challenges with the patterns shown above

Remember that migration is a process, not an event.

It's okay to have a mixed codebase during the transition period.

The important thing is to keep making progress while maintaining code quality.

Ready to Start Your Migration?

Begin by setting up TypeScript in your project and gradually adding type annotations.

The TypeScript compiler will guide you through the process of making your code more robust and maintainable.

For more information, check out the official TypeScript migration guide.




×

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail:
[email protected]

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail:
[email protected]

W3Schools is optimized for learning and training. Examples might be simplified to improve reading and learning. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. While using W3Schools, you agree to have read and accepted our terms of use, cookie and privacy policy.

Copyright 1999-2025 by Refsnes Data. All Rights Reserved. W3Schools is Powered by W3.CSS.