DevToolBoxFREE
Blog

TypeScript to JavaScript: Complete Conversion Guide

12 min readby DevToolBox

Converting TypeScript to JavaScript is a common task when publishing npm packages, supporting legacy environments, or removing type overhead from production bundles. Whether you need to convert TS to JS online quickly or set up an automated build pipeline, understanding what gets stripped and what stays is essential. This comprehensive guide covers the TypeScript compiler (tsc), Babel, esbuild, online conversion tools, enum handling, project migration strategies, and best practices for TypeScript to JavaScript conversion.

Try our free online TypeScript to JavaScript Converter.

Why Convert TypeScript to JavaScript?

TypeScript is a superset of JavaScript that adds static type checking, interfaces, enums, generics, and other features. However, browsers and Node.js runtimes execute JavaScript, not TypeScript. Every TypeScript file must be compiled (or transpiled) to JavaScript before it can run. This conversion removes all type annotations while preserving the runtime logic.

Common scenarios for TS to JS conversion include: publishing an npm library that must work in plain JavaScript projects, deploying to environments that do not support TypeScript natively, debugging compiled output to understand what TypeScript generates, migrating away from TypeScript in legacy projects, and reducing build complexity in small scripts or prototypes.

Understanding what changes during conversion helps you write better TypeScript. Type annotations, interfaces, type aliases, and declare blocks are erased completely. Enums, decorators, class fields, and namespace declarations generate runtime JavaScript code. Knowing this distinction is key to predicting your output.

What Gets Stripped: Types vs Runtime Code

When converting TypeScript to JavaScript, it is critical to understand which TypeScript features are erased (type-only) and which produce runtime code:

TypeScript FeatureErased?JavaScript Output
Type annotations (: string, : number)YesRemoved entirely
Interfaces (interface User {})YesRemoved entirely
Type aliases (type ID = string)YesRemoved entirely
Generics (<T>)YesRemoved entirely
as type assertionsYesExpression kept, assertion removed
Enums (enum Direction {})NoGenerates IIFE or object
const enumDependsInlined at usage sites by default
Decorators (@Injectable())NoGenerates decorator call code
Namespace (namespace Foo {})NoGenerates IIFE
Class fields with declareYesRemoved entirely
Parameter properties (constructor(public name: string))NoGenerates assignment in constructor

Methods to Convert TypeScript to JavaScript

Method 1: TypeScript Compiler (tsc)

The official TypeScript compiler (tsc) is the most reliable way to convert TypeScript to JavaScript. It performs full type checking before emitting JavaScript output. Install with npm install -D typescript:

# Install TypeScript
npm install -D typescript

# Create tsconfig.json
npx tsc --init

# tsconfig.json key settings for conversion
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "outDir": "./dist",
    "rootDir": "./src",
    "declaration": true,       // Generate .d.ts files
    "sourceMap": true,          // Generate source maps
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"]
}

# Compile single file
npx tsc src/app.ts --outDir dist

# Compile entire project
npx tsc

# Type-check only (no output)
npx tsc --noEmit

Method 2: Babel with @babel/preset-typescript

Babel strips TypeScript types without performing type checking, making it faster than tsc for build pipelines where type checking runs separately. Install with npm install -D @babel/core @babel/cli @babel/preset-typescript:

# Install Babel with TypeScript preset
npm install -D @babel/core @babel/cli @babel/preset-typescript

# babel.config.json
{
  "presets": ["@babel/preset-typescript"]
}

# Compile a single file
npx babel src/app.ts --out-file dist/app.js --extensions ".ts,.tsx"

# Compile entire directory
npx babel src --out-dir dist --extensions ".ts,.tsx"

# Note: Babel does NOT type-check!
# Run tsc separately for type safety:
npx tsc --noEmit && npx babel src --out-dir dist --extensions ".ts,.tsx"

Method 3: esbuild (Fastest)

esbuild is an extremely fast JavaScript bundler written in Go that natively supports TypeScript. It strips types without type checking, similar to Babel but orders of magnitude faster:

# Install esbuild
npm install -D esbuild

# Bundle a TypeScript entry point to JavaScript
npx esbuild src/app.ts --bundle --outfile=dist/app.js --platform=node

# Transpile without bundling (preserves module structure)
npx esbuild src/**/*.ts --outdir=dist --format=esm

# Watch mode for development
npx esbuild src/app.ts --bundle --outfile=dist/app.js --watch

# Build with minification for production
npx esbuild src/app.ts --bundle --minify --outfile=dist/app.min.js

Method 4: Online Converter

For quick one-off conversions, an online TypeScript to JavaScript converter lets you paste TypeScript code and instantly see the JavaScript output. Our free tool at DevToolBox handles all TypeScript syntax including enums, decorators, and generic type parameters. No installation needed.

Handling TypeScript Enums in JavaScript

TypeScript enums are one of the few TypeScript features that generate runtime JavaScript code. Understanding their compiled output helps you work with the converted JavaScript:

// === TypeScript: Numeric enum ===
enum Direction {
  Up,      // 0
  Down,    // 1
  Left,    // 2
  Right    // 3
}

// === Compiled JavaScript ===
var Direction;
(function (Direction) {
    Direction[Direction["Up"] = 0] = "Up";
    Direction[Direction["Down"] = 1] = "Down";
    Direction[Direction["Left"] = 2] = "Left";
    Direction[Direction["Right"] = 3] = "Right";
})(Direction || (Direction = {}));
// Direction[0] === "Up"   (reverse lookup)
// Direction.Up === 0      (forward lookup)

// === TypeScript: String enum ===
enum Color {
  Red = "#FF0000",
  Green = "#00FF00",
  Blue = "#0000FF"
}

// === Compiled JavaScript ===
var Color;
(function (Color) {
    Color["Red"] = "#FF0000";
    Color["Green"] = "#00FF00";
    Color["Blue"] = "#0000FF";
})(Color || (Color = {}));
// No reverse mapping for string enums

// === TypeScript: const enum (inlined) ===
const enum Status {
  Active = "ACTIVE",
  Inactive = "INACTIVE"
}
const s = Status.Active;

// === Compiled JavaScript (const enum is inlined) ===
const s = "ACTIVE"; // enum declaration removed entirely

Numeric enums compile to an IIFE (Immediately Invoked Function Expression) that creates a bidirectional mapping object. This means you can look up both the name by value and the value by name.

String enums compile to a simpler object with only forward mappings (name to value). There is no reverse mapping because string values are not guaranteed to be unique.

const enums are inlined at usage sites by default, meaning the enum declaration is completely removed and each reference is replaced with its literal value. This produces the most efficient JavaScript but means you lose the runtime object. Use --preserveConstEnums to keep the runtime object if needed.

Preserving Runtime Behavior

When converting TypeScript to JavaScript, certain patterns require special attention to preserve correct runtime behavior:

Optional chaining and nullish coalescing: TypeScript's ?. and ?? operators are standard JavaScript (ES2020). If your target is ES2019 or earlier, tsc will emit polyfilled versions. If targeting ES2020+, they pass through unchanged.

Parameter properties: TypeScript's constructor(public name: string) shorthand generates assignment statements in the constructor body. The resulting JavaScript is equivalent to manually writing this.name = name.

// === TypeScript: Parameter properties ===
class User {
  constructor(
    public name: string,
    private age: number,
    readonly id: string
  ) {}
}

// === Compiled JavaScript ===
class User {
  constructor(name, age, id) {
    this.name = name;
    this.age = age;
    this.id = id;
  }
}

// === TypeScript: import type (always erased) ===
import type { UserType } from './types';  // Erased completely
import { createUser } from './utils';     // Kept (runtime value)

Import elision: TypeScript automatically removes imports that are only used as types. If an import is used both as a type and a value, TypeScript keeps it. Use import type { Foo } to explicitly mark type-only imports and avoid accidental side effects.

Project Migration: TypeScript to JavaScript

Migrating an entire project from TypeScript to JavaScript is a larger undertaking. Here is a practical approach:

  1. Compile with tsc --declaration: Generate both .js and .d.ts files. The .d.ts files preserve type information for any TypeScript consumers.
  2. Verify output: Run your test suite against the compiled JavaScript to ensure behavior is identical.
  3. Replace source files: Swap .ts files with the compiled .js files. Keep .d.ts files if the project is consumed as a library.
  4. Update build tooling: Remove TypeScript from devDependencies, update build scripts, and remove tsconfig.json if fully migrating away.
  5. Add JSDoc annotations: For projects that still want type checking without TypeScript, use JSDoc comments with // @ts-check and jsconfig.json to get IDE support.

Best Practices for TypeScript to JavaScript Conversion

Use tsc for correctness, esbuild for speed: Run tsc --noEmit for type checking in CI, and use esbuild or Babel for fast builds in development. This gives you both safety and speed.

Set the correct target: The target in tsconfig.json determines which JavaScript version is emitted. Use ES2020 or later for modern environments, ES5 for legacy browser support.

Use module: "ESNext" for tree shaking: ES modules enable bundlers to eliminate unused exports. Avoid "CommonJS" unless targeting Node.js without ESM support.

Prefer import type for type-only imports: This ensures type imports are always erased and prevents accidentally importing runtime code from type-only modules.

Be cautious with enums: If you plan to convert to JavaScript, prefer union types (type Direction = "up" | "down") over enums, as unions are erased completely while enums generate runtime code.

Test the compiled output: Always run your tests against the compiled JavaScript, not just the TypeScript source. This catches issues with enum compilation, decorator output, and module resolution.

Use source maps: Enable "sourceMap": true in tsconfig.json so you can debug the original TypeScript when issues arise in the compiled JavaScript.

Related tools: JSON to TypeScript for generating interfaces, JSON Formatter for validating JSON, and Diff Checker for comparing TypeScript and JavaScript output.

TypeScript to JavaScriptJSON to TypeScriptJSON FormatterDiff Checker

Frequently Asked Questions

Can I convert TypeScript to JavaScript online without installing anything?

Yes. Our free TypeScript to JavaScript converter at DevToolBox lets you paste any TypeScript code and instantly see the compiled JavaScript output. It handles all TypeScript features including generics, enums, interfaces, type aliases, and decorators. No Node.js or npm installation required.

What is the difference between tsc, Babel, and esbuild for TypeScript compilation?

tsc is the official TypeScript compiler that performs full type checking and emits JavaScript. It is the most correct but slowest option. Babel with @babel/preset-typescript strips types without checking them, offering faster builds. esbuild is written in Go and is the fastest option (10-100x faster than tsc), also stripping types without checking. For production, use tsc --noEmit for type checking plus esbuild for fast JavaScript emission.

What happens to TypeScript interfaces and type aliases when converted to JavaScript?

Interfaces and type aliases are completely erased during compilation. They exist only at compile time for type checking and generate zero JavaScript output. This is true for all conversion methods (tsc, Babel, esbuild). Only runtime constructs like enums, decorators, and namespace declarations produce JavaScript code.

How do TypeScript enums compile to JavaScript?

Numeric enums compile to an IIFE that creates a bidirectional mapping object (you can look up name by value and value by name). String enums compile to a forward-only mapping object. const enum values are inlined at usage sites, removing the enum object entirely. Use --preserveConstEnums to keep the runtime object.

Should I convert an existing TypeScript project to JavaScript?

In most cases, no. TypeScript provides significant benefits for code quality, refactoring safety, and developer experience. Consider converting only if: the project is very small and TypeScript adds unnecessary complexity, the team has no TypeScript expertise, or you are publishing a library and want to provide pre-compiled JavaScript with .d.ts type definitions.

Converting TypeScript to JavaScript is straightforward once you understand what gets stripped (types, interfaces, aliases) and what generates runtime code (enums, decorators, namespaces). Use tsc for correctness, esbuild for speed, and our free online converter for quick one-off tasks. This guide covers everything you need for confident TS to JS conversion.

Convert TypeScript to JavaScript instantly with our free online tool.

Related Developer Tools and Guides

𝕏 Twitterin LinkedIn
Was this helpful?

Stay Updated

Get weekly dev tips and new tool announcements.

No spam. Unsubscribe anytime.

Try These Related Tools

JSTypeScript to JavaScript{ }JSON Formatter

Related Articles

TypeScript vs JavaScript: When to Use Which

A practical comparison of TypeScript and JavaScript. Type safety, code examples, migration strategies, performance, ecosystem, and a decision framework for choosing the right language.

TypeScript Generics Complete Guide 2026: From Basics to Advanced Patterns

Master TypeScript generics with this comprehensive guide covering type parameters, constraints, conditional types, mapped types, utility types, and real-world patterns like event emitters and API clients.

TypeScript Utility Types Cheat Sheet: Partial, Pick, Omit, and More

Complete reference for TypeScript utility types with practical examples. Learn Partial, Required, Pick, Omit, Record, Exclude, Extract, ReturnType, and advanced patterns.