TypeScript to JavaScript
Strip TypeScript types to plain JavaScript as you type — interfaces, generics and annotations gone, your syntax untouched — entirely on this device.
Types are removed, never type-checked — your JavaScript syntax is passed through untouched.
TSX keeps JSX in the output — tags such as <div> are preserved verbatim, never compiled to React.createElement.
Press ? for shortcuts
Do it offline:$ npx sucrase src -d dist --transforms typescript --disable-es-transforms
How to use it
- Paste TypeScript or drop a .ts file up to 4 MB — it is read inside the page, never uploaded, and a short paste converts as you type.
- Choose TS for ordinary TypeScript, or TSX when the code holds JSX tags, since the two modes read angle brackets differently.
- Read the output beside the status line, which reports either that types were stripped or that the input already was plain JavaScript.
- Take the result with Copy, save it as a .js or .jsx file, or share a permalink that reopens this converter unchanged.
TypeScript turns into JavaScript here by removing the types and leaving everything else alone: interfaces, annotations, generics and as assertions disappear, while the JavaScript underneath is copied through character for character. It is a strip, not a compiler — modern syntax such as ?. and ?? is preserved, nothing is lowered to an older JavaScript version, and no type errors are reported, because the sucrase engine parses your code without ever type-checking it.
Examples
interface Point { x: number; y: number }
const origin: Point = { x: 0, y: 0 };
const scale = (p: Point, k: number): Point => ({ x: p.x * k, y: p.y * k });
const origin = { x: 0, y: 0 };
const scale = (p, k) => ({ x: p.x * k, y: p.y * k });The interface disappears and its line comes back empty, the annotation on origin is gone, and the scale arrow keeps its parameter names but sheds every type.
enum Level { Low, Medium, High }var Level; (function (Level) { const Low = 0; Level[Level["Low"] = Low] = "Low"; const Medium = Low + 1; Level[Level["Medium"] = Medium] = "Medium"; const High = Medium + 1; Level[Level["High"] = High] = "High"; })(Level || (Level = {}));An enum is a value as well as a type, so it cannot simply vanish: it compiles to a real object built by an immediately-invoked function, which is why one short line expands into the block above.
const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
const inRange = clamp(120, 0, 100);const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
const inRange = clamp(120, 0, 100);There is no TypeScript-only syntax to remove, so the output equals the input byte for byte and the status line says the code already was plain JavaScript.
const badge: JSX.Element = <span className="tag" title={label}>{label}</span>;const badge = <span className="tag" title={label}>{label}</span>;In TSX mode the JSX.Element annotation is removed while the markup stays as written. The tool never rewrites JSX into function calls, since that would be a transpile, not a strip; in TS mode the same line is a parse error.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Types removed, syntax untouched
Only the type layer is deleted. Modern JavaScript rides through byte for byte — optional chaining written a?.b, the ?? operator and #private class fields all reach the output as written — because down-levelling is switched off.
Enums and parameter properties become runtime code
A strip is usually a deletion, but not always. An enum becomes a real object built at load time, and a constructor parameter marked private expands into an assignment such as this.url = url. Both add code rather than remove it.
Namespaces that hold values are dropped
sucrase cannot keep a TypeScript namespace or module block that defines real values — it deletes the body, so anything declared inside is gone at run time. The tool warns when it sees one; flatten it into ordinary exports first.
TS and TSX read angle brackets differently
The two modes disagree about the < and > characters. In TS mode <number>value is an old-style type assertion and strips down to value; in TSX mode those same characters begin a JSX element. That disagreement is the whole reason for the toggle.
export = and import = require turn into CommonJS
TypeScript's own module forms are converted, not removed: export = value becomes module.exports = value, and import x = require("pkg") becomes a const binding. Ordinary import and export lines, and a dynamic import() call, are left as they stand.
This strips types; it does not type-check
The converter reports a problem only when the source cannot be parsed. It will not flag a value of the wrong type, an undeclared name or an unsatisfied interface — that is a type-checker's work, and skipping it is the deliberate line between this tool and tsc.
Common errors
Unexpected token at line 1, column 12.- A type annotation opened with a colon but no type followed before the equals sign, so the parser stopped at the unexpected token. Jump to error moves the caret there.
Unexpected token, expected ">" at line 1, column 34.- This is JSX pasted while the mode is still TS, which reads a leading angle bracket as a generic and trips over the JSX attribute. Switch to TSX and the same code converts.
This tool strips up to 4MB of TypeScript; beyond that, try the CLI: npx sucrase src -d dist --transforms typescript --disable-es-transforms- Past four megabytes the converter turns the paste down rather than work on a fragment; your code stays put. The command runs the same sucrase transform on your machine.
FAQ
Does stripping types change how my JavaScript runs?
Almost never. The type layer is erased and the runtime code is copied through unchanged, so behaviour matches — with two documented exceptions that add code, an enum and a parameter property. The test suite re-runs every example here through the engine.
Why does converting an enum produce so much code?
Because an enum is a value, not only a type. It lives at run time as an object you can index both ways, so the converter has to emit the small function that builds it. For a clean strip, prefer a union of string literals or a plain object.
Is this the same as running the TypeScript compiler?
No. tsc checks your types and can emit older JavaScript; this tool does neither. It removes the types and returns modern JavaScript with the syntax intact, but never reports a type mismatch.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Convert the buffer, or re-run after switching mode.
- ⌘/Ctrl + S
- Download the output under its .js or .jsx name.
- ⌘/Ctrl + C
- Copy the converted JavaScript when nothing is selected.
- ⌘/Ctrl + Shift + C
- Force-copy the whole output over a selection.
- t
- Switch the color theme between light and dark.
- ? or ⌘/Ctrl + /
- Open help listing every shortcut on this page.
- Esc
- Close the open dialog without losing your input.