← Back to TypeScript Course | Chapter 25: Build Tools | Lesson 6 of 6

Babel with TypeScript

Babel can strip TypeScript syntax and transform modern JavaScript. A separate TypeScript checker is normally used because Babel does not perform TypeScript type checking.

Core Concept

Babel can compile TypeScript syntax via @babel/preset-typescript, which — like esbuild and SWC — strips type annotations without validating them, letting Babel's existing plugin ecosystem (JSX, decorators, etc.) apply uniformly to typed and untyped code alike.

Example: Core Concept

typescript
// @babel/preset-typescript strips type annotations, doesn't validate them
console.log("Babel treats TypeScript syntax the same as any other preset");

Basic Setup

A basic setup adds @babel/preset-typescript to the presets array in babel.config.js alongside @babel/preset-env, so .ts/.tsx files pass through the same pipeline as your JavaScript.

Example: Basic Setup

typescript
// babel.config.js
// presets: ["@babel/preset-env", "@babel/preset-typescript"]
console.log("preset-typescript lets .ts/.tsx pass through Babel's pipeline");

Typed Example

Because Babel only strips types, TypeScript-only features that require actual type information to compile — like const enum inlining or legacy experimental decorators' full metadata — either behave differently or need extra flags under Babel's preset.

Example: Typed Example

typescript
// const enum inlining and legacy decorator metadata need extra
// handling under Babel's type-stripping approach.
console.log("Some TypeScript-only features behave differently under Babel");

Project Usage

In a real project, Babel with the TypeScript preset is common when you already depend on Babel's plugin ecosystem for something tsc doesn't do alone, like custom JSX transforms or targeting very old browsers.

Example: Project Usage

typescript
// Useful when you already depend on Babel's JSX/plugin ecosystem
console.log("Babel + TypeScript preset fits projects with existing Babel plugins");

Best Practices

Always run tsc --noEmit alongside Babel compilation for real type checking, and be aware some valid TypeScript patterns (namespaces used for merging, certain enum forms) aren't fully supported by Babel's type-stripping approach.

Example: Best Practices

typescript
// package.json: "typecheck": "tsc --noEmit"
console.log("Always run tsc --noEmit alongside Babel for real type checking");
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.