or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-babel--plugin-transform-typescript

Babel plugin that transforms TypeScript code into ES.next JavaScript by stripping TypeScript-specific syntax while preserving runtime behavior.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@babel/plugin-transform-typescript@7.28.x

To install, run

npx @tessl/cli install tessl/npm-babel--plugin-transform-typescript@7.28.0

index.mddocs/

Babel Plugin Transform TypeScript

A Babel plugin that transforms TypeScript code into ES.next JavaScript by stripping TypeScript-specific syntax including type annotations, interfaces, enums, and other TypeScript constructs while preserving runtime behavior.

Package Information

  • Package Name: @babel/plugin-transform-typescript
  • Package Type: npm
  • Language: JavaScript/TypeScript
  • Installation: npm install --save-dev @babel/plugin-transform-typescript

Core Imports

This plugin is not imported directly in code. Instead, it's configured in Babel configuration files:

Babel Config (.babelrc.json):

{
  "plugins": ["@babel/plugin-transform-typescript"]
}

Babel Config (babel.config.js):

module.exports = {
  plugins: ["@babel/plugin-transform-typescript"]
};

Programmatic Usage:

import babel from "@babel/core";
import transformTypeScript from "@babel/plugin-transform-typescript";

const result = babel.transformSync(code, {
  plugins: [transformTypeScript]
});

Basic Usage

The plugin automatically transforms TypeScript syntax when processing files through Babel:

Input TypeScript:

interface User {
  name: string;
  age: number;
  isActive?: boolean;
}

class UserManager {
  private users: User[] = [];
  
  addUser(user: User): void {
    this.users.push(user);
  }
  
  getActiveUsers(): User[] {
    return this.users.filter(u => u.isActive);
  }
}

enum Status {
  Active = "active",
  Inactive = "inactive"
}

Output JavaScript:

class UserManager {
  constructor() {
    this.users = [];
  }
  
  addUser(user) {
    this.users.push(user);
  }
  
  getActiveUsers() {
    return this.users.filter(u => u.isActive);
  }
}

var Status = function(Status) {
  Status["Active"] = "active";
  Status["Inactive"] = "inactive";
  return Status;
}({});

Architecture

The plugin operates as a Babel transform that:

  • Strips Type Annotations: Removes all TypeScript type information while preserving runtime behavior
  • Transforms Enums: Converts TypeScript enums to JavaScript objects or optimized const enum inlining
  • Handles Namespaces: Transforms namespace declarations to JavaScript module patterns
  • Manages Imports/Exports: Removes type-only imports and exports
  • Preserves Classes: Maintains class structure while removing TypeScript-specific features

Capabilities

Plugin Configuration

Configure the plugin behavior through options passed to Babel.

interface Options {
  /** Allow namespace declarations (default: true) */
  allowNamespaces?: boolean;
  /** JSX pragma function (default: "React.createElement") */
  jsxPragma?: string;
  /** JSX fragment pragma (default: "React.Fragment") */
  jsxPragmaFrag?: string;
  /** Only remove type-only imports/exports (default: false) */
  onlyRemoveTypeImports?: boolean;
  /** Optimize const enums by inlining values (default: false) */
  optimizeConstEnums?: boolean;
  /** Allow declare field modifiers (default: false, Babel 7 only - removed in Babel 8) */
  allowDeclareFields?: boolean;
  
  // Inherited from @babel/plugin-syntax-typescript:
  /** Disallow ambiguous JSX-like expressions (default: false) */
  disallowAmbiguousJSXLike?: boolean;
  /** Process .d.ts declaration files (default: false) */
  dts?: boolean;
  /** Enable TSX (JSX in TypeScript) parsing (default: false) */
  isTSX?: boolean;
}

Usage with Options:

{
  "plugins": [
    ["@babel/plugin-transform-typescript", {
      "allowNamespaces": false,
      "onlyRemoveTypeImports": true,
      "optimizeConstEnums": true
    }]
  ]
}

Type Stripping

Removes TypeScript type annotations while preserving runtime behavior.

Transformations handled:

  • Interface declarations → Removed completely
  • Type aliases → Removed completely
  • Function type annotations → Parameters and return types stripped
  • Variable type annotations → Type information removed
  • Generic type parameters → Removed from functions, classes, interfaces
  • Type assertions → value as Type becomes value
  • Non-null assertions → value! becomes value

Enum Transformation

Transforms TypeScript enums to JavaScript objects with proper value assignment, including advanced features like enum merging and cross-references.

Regular Enums:

// Input
enum Direction {
  Up,
  Down,
  Left = "left",
  Right = "right"
}

// Output  
var Direction = function(Direction) {
  Direction[Direction["Up"] = 0] = "Up";
  Direction[Direction["Down"] = 1] = "Down";
  Direction["Left"] = "left";
  Direction["Right"] = "right";
  return Direction;
}({});

Const Enums (with optimizeConstEnums: true):

// Input
const enum Status {
  Loading = "loading",
  Success = "success"
}
console.log(Status.Loading);

// Output
console.log("loading");

Enum Cross-References and Mathematical Operations:

// Input
enum Values {
  A = 1,
  B = A * 2,
  C = B + A,
  D = Math.floor(3.14)
}

// Output
var Values = function(Values) {
  Values[Values["A"] = 1] = "A";
  Values[Values["B"] = 2] = "B";
  Values[Values["C"] = 3] = "C";
  Values[Values["D"] = 3] = "D";
  return Values;
}({});

Enum Declaration Merging:

// Input
enum Color { Red, Green }
enum Color { Blue = 2 }

// Output - Merges into single enum object
var Color = function(Color) {
  Color[Color["Red"] = 0] = "Red";
  Color[Color["Green"] = 1] = "Green";
  Color[Color["Blue"] = 2] = "Blue";
  return Color;
}({});

Namespace Transformation

Transforms TypeScript namespace declarations to JavaScript patterns when allowNamespaces is enabled, including support for qualified names and strict export restrictions.

Basic Namespace:

// Input
namespace Utils {
  export function helper() { return "help"; }
  export const VERSION = "1.0";
}

// Output
var Utils = function() {
  function helper() { return "help"; }
  const VERSION = "1.0";
  return { helper, VERSION };
}();

Qualified Namespace Names:

// Input
namespace A.B.C {
  export const value = 42;
}

// Output
var A = A || {};
A.B = A.B || {};
A.B.C = function() {
  const value = 42;
  return { value };
}();

Namespace Export Restrictions: Namespaces can only export const declarations, functions, classes, and other namespaces. Non-const variable exports will cause compilation errors:

// This will fail:
namespace Utils {
  export let mutableValue = 1; // Error: only const exports allowed
}

// This works:
namespace Utils {
  export const immutableValue = 1; // OK
  export function doSomething() {} // OK
}

Import/Export Handling

Removes type-only imports and exports while preserving value imports.

Type Import Removal:

// Input
import type { User } from './types';
import { UserService, type Config } from './service';

// Output  
import { UserService } from './service';

Export Handling:

// Input
export type { User };
export { UserService, type Config };

// Output
export { UserService };

Class Member Processing

Handles TypeScript class features while preserving JavaScript class behavior.

Parameter Properties:

// Input
class User {
  constructor(
    public name: string,
    private age: number,
    readonly id: string
  ) {}
}

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

Parameter Property Restrictions: Parameter properties cannot use destructuring patterns:

// This will fail:
class User {
  constructor(
    public { name, age }: UserData, // Error: destructuring not allowed
    private options?: { debug: boolean }
  ) {}
}
// Error: "Parameter properties can not be destructuring patterns"

Field Declarations:

// Input
class Service {
  private cache?: Map<string, any>;
  public readonly version: string = "1.0";
  declare ready: boolean;
}

// Output
class Service {
  constructor() {
    this.version = "1.0";
  }
}

JSX Integration

Handles TypeScript-specific JSX features while preserving React JSX transformation.

Generic JSX:

// Input
const element = <Component<string> value="test" />;

// Output
const element = React.createElement(Component, { value: "test" });

Type Arguments Removal:

// Input
createElement<Props>(Component, props);

// Output  
createElement(Component, props);

Module Compatibility

Supports CommonJS export assignment transformation when CommonJS modules are enabled.

// Input (TypeScript module syntax)
export = myFunction;

// Output (CommonJS)
module.exports = myFunction;

Error Handling

The plugin throws compilation errors for unsupported patterns with specific error messages:

Configuration Errors

Namespace errors (when allowNamespaces: false):

// Error message when namespaces are disabled but used
"Namespaces are not supported when allowNamespaces is false"

Declare fields without allowDeclareFields (Babel 7 only):

// Error message when using declare without enabling the option
"The 'declare' modifier is only allowed when the 'allowDeclareFields' option of @babel/plugin-transform-typescript or @babel/preset-typescript is enabled"

TypeScript Syntax Errors

Parameter property destructuring:

// This will fail:
class User {
  constructor(
    public { name, age }: UserData // Error: destructuring not allowed
  ) {}
}
// Error: "Parameter properties can not be destructuring patterns"

Declare fields with initializers:

// This will fail:
class Service {
  declare initialized: boolean = true; // Error: declare fields cannot have initializers
}
// Error: "Fields with the 'declare' modifier cannot be initialized here, but only in the constructor"

Definitely assigned fields with initializers:

// This will fail:
class Service {
  ready!: boolean = false; // Error: definite assignment with initializer
}
// Error: "Definitely assigned fields cannot be initialized here, but only in the constructor"

CommonJS Transform Errors

Export assignment without CommonJS transform:

// This will fail without @babel/plugin-transform-modules-commonjs:
export = myFunction;
// Error: "`export = <value>;` is only supported when compiling modules to CommonJS. Please consider using `export default <value>;`, or add @babel/plugin-transform-modules-commonjs to your Babel config"

Import equals without CommonJS transform:

// This will fail without CommonJS transform:
import foo = require('./bar');
// Error: "`import foo = require(...);` is only supported when compiling modules to CommonJS. Please consider using `import foo from '...';` alongside TypeScript's --allowSyntheticDefaultImports option"

Namespace Export Errors

Non-const variable exports in namespaces:

// This will fail:
namespace Utils {
  export let mutable = 1; // Error: only const exports allowed
}
// Error: "Namespaces exporting non-const are not supported by Babel. Change to const or see: https://babeljs.io/docs/en/babel-plugin-transform-typescript"

Nested ambient modules:

// This will fail:
declare module "outer" {
  declare module "inner" {} // Error: nested ambient modules not supported
}

Enum Errors

Enum member without initializer after string member:

// This will fail:
enum Mixed {
  A = "string",
  B // Error: must have initializer after string member
}
// Error: "Enum member must have initializer"

Version Compatibility

The plugin behavior differs between Babel 7 and Babel 8:

Babel 7 Specific Features

  • allowDeclareFields option: Available in Babel 7 to control handling of declare field modifiers
  • Definite assignment handling: Fields with definite assignment (!) are removed when allowDeclareFields: false
  • Export assignments: Support for import foo = require() syntax with isExport property

Babel 8 Changes

  • allowDeclareFields removed: The allowDeclareFields option is not available in Babel 8
  • Stricter field handling: Definite assignment fields and declare fields are handled more strictly
  • Updated AST properties: Some node properties have been renamed (e.g., superTypeParameterssuperTypeArguments)
  • Enhanced type argument handling: Improved handling of generic type arguments in JSX and expressions

Migration Notes

When upgrading from Babel 7 to Babel 8:

  1. Remove allowDeclareFields option from configuration
  2. Review class field declarations that use declare or definite assignment (!)
  3. Update any custom transforms that depend on legacy AST property names
  4. Test enum and namespace transformations as the underlying implementation has been optimized

Plugin Integration

With TypeScript Preset:

{
  "presets": [
    ["@babel/preset-typescript", {
      "allowNamespaces": true,
      "onlyRemoveTypeImports": false
    }]
  ]
}

Standalone Plugin Usage:

{
  "plugins": [
    "@babel/plugin-syntax-typescript",
    ["@babel/plugin-transform-typescript", {
      "allowNamespaces": false
    }]
  ]
}

The plugin requires @babel/plugin-syntax-typescript for parsing TypeScript syntax and automatically inherits from it when used.