NIXX/DEVv1.14.0
ArticlesFavorites
Sign In
Sign In
Articles

Welcome to our blog

A curated collection of insightful articles, practical guides, and expert tips designed to simplify your workflow

Cover image for: How to Convert a JS Project to TypeScript in 5 Steps
July 29, 20256 MIN READ min readBy ℵi✗✗

How to Convert a JS Project to TypeScript in 5 Steps

Migrating from JavaScript to TypeScript doesn’t have to be overwhelming. Here’s a simple, step-by-step guide to help you upgrade your project with confidence.

productivityjavascripttypescriptrefactoring
ℵi✗✗

ℵi✗✗

Full-Stack Developer

Passionate about building tools and sharing knowledge with the developer community.

Was this helpful?

Popular Posts

  • NixOS vs. Arch Linux: Which One Belongs in Your Dev Setup?

    NixOS vs. Arch Linux: Which One Belongs in Your Dev Setup?

    5 MIN READ min read

  • How to Enable HTTPS on Localhost in Under 2 Minutes

    How to Enable HTTPS on Localhost in Under 2 Minutes

    3 MIN READ min read

  • Migrating from Create React App (CRA) to Vite: A Step-by-Step Guide

    Migrating from Create React App (CRA) to Vite: A Step-by-Step Guide

    4 MIN READ min read

  • Array Destructuring in PHP: A Practical Guide for Modern Developers

    Array Destructuring in PHP: A Practical Guide for Modern Developers

    5 MIN READ min read

Recommended Products

  • Apple iPad (7th Gen)

    Apple iPad (7th Gen)

    4.3
  • Fitbit Versa 4

    Fitbit Versa 4

    4.3
  • JBL Flip 6

    JBL Flip 6

    4.8
  • Dell 24 Monitor — SE2425HM Full HD

    Dell 24 Monitor — SE2425HM Full HD

    4.7

May contain affiliate links

Topics

webdev33productivity16cybersecurity12javascript11automation9guide8react7typescript7php6tutorial6freelancing5github actions5privacy5how to4Node.js4
+111 more topics →
🇺🇸USD ACCOUNTOpen a free US-based USD accountReceive & save in USD — powered by ClevaSponsoredInterserver Hosting#1 VALUEAffordable, reliable hosting from $2.50/mo99.9% uptimeSponsored

Migrating a project from JavaScript to TypeScript is one of the more common decisions developers face as a codebase grows and the cost of runtime bugs increases. The good news is that TypeScript is designed for incremental adoption. There is no requirement to type every file before the project becomes useful. A partial migration still produces real benefits: better editor support, compiler-enforced null checking in the files that have been converted, and safer refactoring in the areas that matter most.

This guide covers a practical five-step migration path. Each step builds on the previous one and produces a working codebase at every stage, so the migration can be paused and resumed without leaving the project in a broken state. **What this covers:

  • Installing TypeScript and configuring tsconfig.json

  • Renaming files and enabling incremental compilation

  • Fixing initial type errors without blocking progress

  • Enabling stricter compiler checks gradually

  • Replacing any with specific types over time


Step 1: Install TypeScript and Generate a Config

Install TypeScript as a development dependency:

npm install -D typescript

Generate a tsconfig.json with default settings:

npx tsc --init

The generated file contains a large number of commented-out options. The relevant settings for a migration are:

{
    "compilerOptions": {
        "target": "ES2020",
        "module": "commonjs",
        "strict": false,
        "allowJs": true,
        "checkJs": false,
        "outDir": "./dist",
        "esModuleInterop": true,
        "skipLibCheck": true
    },
    "include": ["src"]
}

Setting strict: false and allowJs: true at the start allows JavaScript and TypeScript files to coexist in the same project without requiring every file to be fully typed immediately. checkJs: false prevents TypeScript from type-checking plain .js files, which would produce a large number of errors before any migration work has been done.

For React projects, add "jsx": "react-jsx" to compilerOptions. For Next.js or Vite, check the framework's documentation for the recommended tsconfig base configuration, as both provide starter configurations that account for framework-specific requirements.


Step 2: Rename Files from .js to .ts

Start with a small, self-contained part of the codebase: a utility module, a set of helper functions, or a single service file. Rename the .js files to .ts.

For files containing JSX (React components), rename to .tsx rather than .ts. TypeScript requires the .tsx extension to parse JSX syntax correctly.

Renaming does not immediately make the code typed. It tells the TypeScript compiler to process the file and report type errors. At this stage, the editor will begin showing type hints and flagging obvious issues. Expect to see errors — they are the migration pointing out what needs attention.

A practical migration order:

  1. Utility functions and helpers (fewest dependencies, easiest to type)

  2. Type definitions and interfaces (enables typing the rest of the codebase)

  3. Service and data-access layers

  4. Components or controllers

  5. Entry points and configuration files

Converting files in this order means the foundational types are in place before the files that depend on them are converted.


Step 3: Fix Initial Type Errors

After renaming the first batch of files, address the errors TypeScript reports. The goal at this stage is to make the project compile without changing application behavior.

The most common initial errors:

Implicit any on function parameters. TypeScript infers any when a parameter has no type annotation, which it may flag depending on configuration. Add a specific type if it is straightforward; use any as a temporary placeholder if the correct type is not immediately clear:

// Temporary — replace with a specific type later
function greet(name: any): string {
    return `Hello, ${name}`;
}

Missing type definitions for external packages. If a library does not ship with TypeScript types, the compiler will report it cannot find a type declaration for the module. Install the corresponding @types/ package:

npm install -D @types/lodash
npm install -D @types/express

Most popular packages have community-maintained type definitions via the DefinitelyTyped repository. Search at npmjs.com for @types/package-name to check availability. If no types exist, a minimal declaration file suppresses the error:

// src/types/missing-module.d.ts
declare module 'package-without-types';

Object property access errors. TypeScript may flag property access on objects whose shape is not yet defined. Defining an interface or type for the object resolves this:

interface User {
    id: number;
    name: string;
    email: string;
}

The measure of success at this stage is a clean npx tsc --noEmit run with no compilation errors. Application behavior should be identical to before the migration started.


Step 4: Enable Stricter Checks Gradually

Once the project compiles cleanly with the initial configuration, stricter compiler options can be enabled incrementally. Turning on strict: true immediately on a partially-migrated codebase will produce a large number of errors. Enabling flags one at a time is more manageable.

A recommended progression:

// Phase 1 — enable after initial migration
{
    "compilerOptions": {
        "noImplicitAny": true
    }
}

noImplicitAny requires every parameter and variable to have an explicit type or a type that can be inferred from context. This is the single highest-value strictness flag because it eliminates the implicit any placeholders that undermine type safety.

// Phase 2 — enable after noImplicitAny is clean
{
    "compilerOptions": {
        "strictNullChecks": true
    }
}

strictNullChecks treats null and undefined as distinct types rather than assignable to everything. This forces explicit handling of nullable values, which prevents the most common category of JavaScript runtime errors.

// Phase 3 — enable full strict mode
{
    "compilerOptions": {
        "strict": true
    }
}

strict: true enables noImplicitAny, strictNullChecks, and several additional checks together. Reaching this point means the codebase has the full benefits of TypeScript's type system.

Fix all errors introduced by each flag before enabling the next one. The incremental approach makes each batch of errors manageable and keeps the project in a compilable state throughout.


Step 5: Replace any with Specific Types

With strict mode enabled, the remaining work is replacing the any placeholders used during migration with accurate type annotations. This is where the long-term maintainability benefits of TypeScript are fully realized.

Specific replacements to look for:

Primitive types for straightforward values:

function greet(name: string): string {
    return `Hello, ${name}`;
}

Interfaces and type aliases for objects:

interface ApiResponse {
    data: User[];
    total: number;
    page: number;
}

unknown instead of any for values whose type is genuinely uncertain. Unlike any, unknown requires a type check before the value can be used:

function parseInput(input: unknown): string {
    if (typeof input === 'string') {
        return input.toUpperCase();
    }
    throw new TypeError('Expected a string');
}

Generic types for reusable functions and data structures:

function first<T>(arr: T[]): T | undefined {
    return arr[0];
}

This step has no fixed end date. In a large codebase, replacing all uses of any is a long-term effort. Prioritize the types that provide the most value: API boundaries, shared utility functions, and the data models that flow through the most code paths.


Migration Checklist

Step

Task

Success criteria

1

Install TypeScript, generate tsconfig.json

npx tsc --noEmit runs without crashing

2

Rename files to .ts / .tsx

Files are processed by the compiler

3

Fix initial errors, use any as placeholder

Project compiles cleanly with no errors

4

Enable noImplicitAny, then strictNullChecks, then strict

Each phase compiles cleanly

5

Replace any with specific types

any usage is progressively eliminated


Key Takeaways

  • Start with strict: false and allowJs: true to allow JavaScript and TypeScript files to coexist during migration.

  • Convert files in dependency order: utilities and type definitions first, components and entry points last.

  • Use any as a temporary placeholder during initial conversion. Its purpose is to keep the project compiling while migration is in progress, not as a permanent type.

  • Enable strictness flags incrementally: noImplicitAny first, then strictNullChecks, then full strict mode.

  • unknown is a safer alternative to any for values whose type is genuinely uncertain. It requires a type guard before use.

  • Replacing any with accurate types is a long-term effort. Prioritize API boundaries and shared data models.


Conclusion

A JavaScript-to-TypeScript migration is not a single event. It is a gradual process that improves the codebase at each step. The approach described here keeps the project working throughout, produces meaningful type coverage early, and allows strictness to be increased at a pace that matches the team's capacity.

A partial migration is better than no migration. Even converting the core utilities and data models while leaving other files as JavaScript provides measurable benefits in the areas that matter most.


Working through a migration and hitting a specific problem — a tricky type, a library without definitions, or a configuration that isn't behaving as expected? Describe it in the comments.

Topics
productivityjavascripttypescriptrefactoring

Discussion

Join the discussion

Sign in to share your thoughts and engage with the community.

Sign In
Loading comments…

Continue Reading

More Articles

View all
Cover image for: How Much Does Business Email Really Cost? (And How to Save Money)
May 25, 20254 MIN READ min read

How Much Does Business Email Really Cost? (And How to Save Money)

If you're paying for business email through Google Workspace or Microsoft 365, you might be overpaying. Here's how to rethink your setup and save hundreds per year.

Cover image for: What Is Identity Theft (and How to Protect Yourself Online)
Nov 17, 20256 MIN READ min read

What Is Identity Theft (and How to Protect Yourself Online)

Identity theft can happen to anyone — often without you even realizing it. Learn what it means, how it happens, and the smart steps you can take today to keep your personal information safe online.

Cover image for: Why You Should Use TypeScript in Every JavaScript Project
Jul 23, 20255 MIN READ min read

Why You Should Use TypeScript in Every JavaScript Project

JavaScript gets the job done—but TypeScript helps you write cleaner, safer, and easier-to-maintain code. Here’s why it’s worth using everywhere.

Cover image for: React Authentication with JWT: A Step-by-Step Guide
Oct 17, 20257 MIN READ min read

React Authentication with JWT: A Step-by-Step Guide

Learn how to implement secure JWT authentication in React. From login to route protection and API calls, this guide covers everything you need to know.

|Made with · © 2026|TermsPrivacy
AboutBlogContact

Free, open-source tools for developers and creators · Community driven