Flash cards
Review the key moves
What is the main idea behind TypeScript Migration Guide?
Lesson checks
Practice each idea before moving on
Short Mimo-style checks built from this lesson's code, terms, and sequence.
Which statement best captures the main point of this lesson?
Complete the missing token from the example code.
# Create a new branch ___ the migrationPut the learning moves in the order that makes the concept easiest to apply.
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.
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"Install TypeScript
# Install TypeScript as a dev dependency
npm install --save-dev typescript @types/nodeCreate 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.
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
For large projects, we strongly recommend the gradual migration approach to minimize disruption and make the process more manageable.
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.
ts-migrate
Automated tool for migrating JavaScript to TypeScript
npx ts-migrate-full .GitHub Repository
TypeStat
Converts JavaScript to TypeScript with type safety
npx typestatGitHub Repository
@types Packages
Install type definitions for your dependencies
npm install --save-dev @types/react @types/nodeTypeSearch
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
Example
// 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
Dynamic Properties
Problem: JavaScript often uses objects as dictionaries.
Example
// Before
const user = {};
user.name = 'John'; // Error: Property 'name' does not existSolution: Use index signatures or type assertions.
Example
// 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'; // OKHandling this Context
Problem: this binding issues in callbacks.
Example
class Counter {
count = 0;
increment() {
setTimeout(function() {
this.count++; // Error: 'this' is not defined
}, 1000);
}
}Solution: Use arrow functions or bind this .
Example
// 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.
- 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 .