The basics
What is a TypeScript file?
A .ts file holds source code in TypeScript, a language Microsoft created as a superset of JavaScript: every JavaScript program is also valid TypeScript, and TypeScript adds a way to write down the types of values. A compiler reads those types and reports mistakes, like passing text where a number is expected, before the program ever runs. The file is plain text, so any text editor can open it.
Browsers can't run TypeScript. The types have to be removed first, either by compiling the file to a JavaScript file with tsc or a bundler, or by a runtime that strips them as it loads the file, as Node.js, Deno and Bun do. Either way, what finally runs is JavaScript.
- Types are for the tools, not the running program. They are checked at compile time and erased. At run time, a TypeScript program behaves exactly like the JavaScript left behind.
- Running is not checking. Node.js, Deno, Bun, esbuild and Vite remove types without checking them. Only the TypeScript compiler (
tsc, or your editor using it) reports type errors. .tshas a second meaning. It's also the extension of MPEG transport stream video, used by TV broadcasts and streaming. How to tell them apart is explained below.
Anatomy
What's inside a TypeScript file
A TypeScript file is JavaScript with extra syntax that describes types: what kind of value each variable, parameter and function result holds. Here is a short module, part by part. Everything that isn't plain JavaScript disappears before the code runs.
import type { User } from "./user.ts";
import { formatName } from "./format.ts";
// One of three allowed values
type Role = "admin" | "editor" | "viewer";
interface Account {
user: User;
role: Role;
lastLogin?: Date;
}
export function greet(account: Account): string {
const name: string = formatName(account.user);
return account.lastLogin
? `Welcome back, ${name}`
: `Welcome, ${name}`;
}
export function first<T>(items: readonly T[]): T | undefined {
return items[0];
}
const roles = ["admin", "editor"] as const satisfies readonly Role[];- 1
import type { User } from "./user.ts";A type-only import
Brings in a type, not a value, so it can be removed completely. Node.js needs the
typekeyword here, or it looks for a value calledUserat run time and fails. - 2
import { formatName } from "./format.ts";A value import
An ordinary ES module import. Writing the
.tsextension is what Node.js, Deno and Bun expect; fortscit needs a setting, explained below. - 3
type Role = "admin" | "editor" | "viewer";A type alias with a union
Rolemay only be one of three strings. A typo such as"admim"is a compile error instead of a bug found later. - 4
interface Account { … }An interface
Describes the shape of an object: which properties it has and their types. Interfaces produce no JavaScript at all.
- 5
lastLogin?: Date;An optional property
The
?means the property may be missing, so the compiler makes you check for it before use. - 6
greet(account: Account): stringParameter and return types
The colon annotations say what goes in and what comes out. Calling
greetwith the wrong object, or using its result as a number, is caught before running. - 7
const name: string = …A variable annotation
Optional most of the time: TypeScript infers that
nameis a string from what's assigned to it. - 8
first<T>(items: readonly T[]): T | undefinedA generic function
Tstands for whatever type the caller passes, sofirst([1, 2])returns a number andfirst(["a"])a string. - 9
as const satisfies readonly Role[]`as const` and `satisfies`
as constkeeps the exact values instead of widening them tostring[];satisfieschecks them against a type without changing it.
Under the hood
How a .ts file becomes running code
There are two ways to get from TypeScript to running code, and most projects use both: a fast tool that only removes types, and the compiler to check them.
| Tool | Checks types? | What it does | Command |
|---|---|---|---|
| TypeScript compiler | Yes | Checks, then writes .js files (plus .d.ts and .map files if asked) | npx tsc (or npx tsc --noEmit to check only) |
| Node.js 22.18+, 23.6+ | No | Runs the file directly, replacing the types with spaces | node app.ts |
| tsx | No | Runs any TypeScript, including enums and JSX, on Node.js; reads tsconfig.json | npx tsx app.ts |
| Deno | Not by default | Runs it directly | deno run app.ts (deno check to check) |
| Bun | No | Runs it directly | bun app.ts |
| esbuild, Vite and other bundlers | No | Remove types while bundling for the browser | npx esbuild app.ts --bundle |
Node.js runs TypeScript by type stripping: it replaces the type syntax with whitespace and runs what's left. Because every line and column stays where it was, error messages point at the right place without a source map. It was enabled by default in Node.js 23.6.0 and backported to 22.18.0, and declared stable in 25.2.0 and 24.12.0. The same node app.ts command works on Windows, macOS and Linux. Here is the anatomy example after stripping, made with Node.js's own stripTypeScriptTypes(): the types have become spaces, and lines that held only types are now blank.
import { formatName } from "./format.ts";
// One of three allowed values
export function greet(account ) {
const name = formatName(account.user);
return account.lastLogin
? `Welcome back, ${name}`
: `Welcome, ${name}`;
}
export function first (items ) {
return items[0];
}
const roles = ["admin", "editor"] ;Stripping only works for TypeScript syntax that can simply be deleted. Node.js refuses features that would need new JavaScript generated: enum, namespace blocks containing code, parameter properties (constructor(private x: number)) and import x = require(). It also ignores tsconfig.json, requires file extensions in imports, and won't run TypeScript inside node_modules. The Node.js documentation recommends these compiler settings, so tsc flags anything Node.js can't run:
{
"compilerOptions": {
"noEmit": true,
"target": "esnext",
"module": "nodenext",
"rewriteRelativeImportExtensions": true,
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true
}
}Extensions
.ts vs .mts vs .cts vs .d.ts vs .tsx
The extension tells the compiler and runtimes how to treat the file, the same way .mjs and .cjs do for JavaScript:
| Extension | What it is | Compiles to |
|---|---|---|
.ts | TypeScript. ES module or CommonJS depending on the nearest package.json "type" field, as for .js | .js |
.mts | Always an ES module (import/export) | .mjs |
.cts | Always CommonJS (require/module.exports) | .cjs |
.d.ts | A declaration file: types only, no code. Describes JavaScript that lives elsewhere, such as a library | Nothing; it's read, never run |
.d.mts, .d.cts | Declarations for .mjs and .cjs files | Nothing |
.tsx | TypeScript with JSX tags, used for React components. See the TSX file | .js, or .jsx with "jsx": "preserve" |
Declaration files are how editors know the types of plain JavaScript packages. tsc --declaration writes them next to compiled output, and packages without their own are often covered by a separate @types/… package, such as @types/node.
Project files
tsconfig.json: the file that sets up a project
A tsconfig.json in a folder marks the root of a TypeScript project. Running tsc with no file names compiles everything it includes, with its settings. Editors read it too, so the errors you see while typing match the build.
{
"compilerOptions": {
"target": "es2022",
"module": "nodenext",
"strict": true,
"outDir": "dist",
"declaration": true,
"sourceMap": true
},
"include": ["src"]
}target: which JavaScript version to output. Newer syntax is rewritten for older targets.module: which module system to output and how imports are resolved.nodenextfollows Node.js's own rules.strict: turns on the stricter checks, such as reporting values that might benull.outDir,declaration,sourceMap: where the.jsgoes, and whether to also write.d.tsdeclaration files and source maps.noEmit: check only, write nothing. Common when another tool does the building.
TypeScript 7 changed some defaults
In TypeScript 7.0, strict is on and module is esnext unless you say otherwise, types defaults to an empty list (add "types": ["node"] to use Node.js's types), and options deprecated in 6.0, such as target: es5, baseUrl and moduleResolution: node10, are now errors. Running tsc file.ts in a folder that has a tsconfig.json is also an error unless you add --ignoreConfig.
Related formats
TypeScript vs JavaScript files
| TypeScript (.ts) | JavaScript (.js) | |
|---|---|---|
| Type annotations | Yes, checked by tsc | No (JSDoc comments can carry types) |
| Runs in a browser | No, compile it first | Yes |
| Runs in Node.js | Yes, in 22.18+ and 23.6+ (erasable syntax only) | Yes |
| Build step | Usually, for browsers and libraries | Optional |
| Mistakes found | While you type, and at compile time | When the code runs |
| Registered MIME type | None | text/javascript |
| Published to npm as | Compiled .js plus .d.ts declarations | .js |
Converting is one-way and easy in one direction: rename a .js file to .ts and it's already TypeScript, with types to add over time. Going back means compiling it, which removes the types.
History
TypeScript versions
| Version | Released | Notable for |
|---|---|---|
| 0.8 | October 2012 | The first public release, a preview |
| 1.0 | April 2014 | The first stable release |
| 4.1 | November 2020 | The react-jsx setting for React's new JSX transform |
| 5.0 | March 2023 | Standard ECMAScript decorators, the bundler module resolution |
| 5.8 | February 2025 | --erasableSyntaxOnly, for code that Node.js can run by stripping types |
| 6.0 | March 2026 | strict on by default; the last compiler written in TypeScript itself |
| 7.0 | July 2026 | The compiler rewritten in Go: Microsoft reports full builds 8 to 12 times faster |
A .ts file doesn't say which TypeScript version it was written for. Code written for one version almost always compiles with the next; what changes between versions is mostly which mistakes the checker catches. TypeScript 7.0 ships without a programmatic API, so tools that embed the compiler can keep using the 6.0 one from the @typescript/typescript6 package for now.
Same extension
Is my .ts file TypeScript or a video?
.ts is also the extension of the MPEG transport stream, the video format of digital TV broadcasts, which is also used for recordings from TV tuners and for segments of streamed video. The two have nothing in common, and telling them apart takes a second:
| TypeScript | MPEG transport stream | |
|---|---|---|
| Content | Readable text | Binary data |
| In a text editor | Code | Garbage characters |
| First byte | Usually /, i, e or another letter (a comment, import, export) | Always 47 (hex), the sync byte |
| Structure | Lines of text | Packets of exactly 188 bytes, each starting with 47 |
| Typical size | A few KB | Megabytes to gigabytes |
| MIME type | None registered | video/mp2t |
| Opens with | A code editor | VLC, mpv, ffmpeg and most video players |
To check the first byte, run head -c 1 file.ts | od -An -tx1 on macOS or Linux, or Format-Hex file.ts | Select-Object -First 1 in PowerShell. A third, rarer .ts is a Qt Linguist translation file: XML that starts with <?xml and contains a <TS> element.
Why servers send TypeScript as video
Many web servers and libraries look up the type by extension, and their tables only know the video meaning: the mime-db list that many Node.js servers use maps .ts and .mts to video/mp2t. A browser opening such a link may try to play or download it. Serve TypeScript as text/plain (or application/typescript) if people should read it in the browser.
Troubleshooting
The TypeScript errors people hit most, and what they mean
| Error message | Usual cause | Fix |
|---|---|---|
| Unknown file extension ".ts" | Node.js older than 22.18 (or 23.6 in the 23 line), or type stripping switched off. In a CommonJS project the same problem shows as a SyntaxError at the first type annotation | Upgrade Node.js, or run it with npx tsx file.ts |
| ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX: TypeScript enum is not supported in strip-only mode | An enum, a parameter property or a namespace with code, which Node.js can't strip | Use a union type or an as const object instead, or run it with tsx; erasableSyntaxOnly makes tsc flag these |
| The requested module './shapes.ts' does not provide an export named 'Shape' | A type imported without import type, so Node.js looks for a value | Write import type { Shape }; verbatimModuleSyntax makes tsc insist on it |
| ERR_MODULE_NOT_FOUND: Cannot find module './shapes' | An import without a file extension | Write the full name: ./shapes.ts |
| TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled | tsc checking code written for Node.js-style imports | Set rewriteRelativeImportExtensions (rewrites them to .js on output) or allowImportingTsExtensions with noEmit |
| TS2591: Cannot find name 'process' | Node.js's types aren't loaded | npm i -D @types/node and add "types": ["node"] to tsconfig.json |
| TS5112: tsconfig.json is present but will not be loaded if files are specified on commandline | tsc file.ts in a project folder, with TypeScript 7 | Run plain tsc, or add --ignoreConfig |
A program with type errors can still run: node, tsx, Bun and bundlers never look at the types. The sample-type-error.ts file below shows this. Run tsc --noEmit before committing or in CI, so type errors stop a build instead of reaching users.
How to
How to open and edit a TypeScript file, and is it safe?
- Edit it: VS Code has TypeScript support built in, with errors underlined as you type and fixes suggested. WebStorm, Zed, Neovim and most other code editors support it too, and any plain-text editor can open the file.
- On Windows: double-clicking a
.tsfile may open a video player, because of the video meaning of the extension. Use Open with, or open it from your editor. - Try it without installing anything: paste it into the TypeScript Playground on typescriptlang.org, which shows the errors and the JavaScript output side by side.
- Run it: install Node.js (22.18 or newer) and run
node file.ts; ornpx tsx file.tsfor files that use enums or other non-erasable syntax. - Convert it to JavaScript:
npx tsc file.tswritesfile.jsnext to it. Online, the Playground's JS tab does the same.
Opening a .ts file in an editor only shows text; nothing runs. Running one with Node.js, Deno or Bun is different: it's a program with the same access to your files and network as any other you start. Unlike .js, Windows doesn't run .ts files with Windows Script Host when they're double-clicked. Types don't make code safe: they catch mistakes, not malicious intent. Read code you didn't write before you run it, and be as careful with npx commands and npm packages as with any software you install.
Free downloads
Sample TypeScript files to download
Free sample TypeScript files for testing compilers, runtimes, editors, linters, upload filters and MIME types. Except the one with a deliberate error, each passes tsc --noEmit in strict mode, and each runnable one runs with node (22.18+), tsx and Bun, with the same output.
Loading…What's inside sample-app.ts
The file is commented: open it in a text editor and each numbered comment marks one of these parts. Run it with node sample-app.ts to see its three lines of output.
Comments 1 and 2: annotations and an interface
Typed
constandletvariables, then aProductinterface with areadonlyproperty and an optionaltagslist.Comments 3 and 4: union and object types
A
Statusthat can only be"pending","paid"or"shipped", and anOrdertype built from the others.Comments 5 to 7: functions
Parameter and return types, a generic
firstOrDefault<T>, and narrowing withtypeofand=== null, where TypeScript knows the exact type inside each branch.Comment 8: `as const` and `satisfies`
A catalogue checked against
Productwithout losing its exact values, with accented product names to show UTF-8 text.Comment 9: a class
A
Basketwith both kinds of privacy:private(checked only by the compiler) and#totalCents(enforced by JavaScript at run time).Comments 10 and 11: async code and output
A function returning
Promise<Order>, then the output:Ada's Café: 2 × Thé vert, 1 × Crème brûlée = €12.25and two more lines.
All sample TypeScript files
Commented sample program
sample-app.ts · 3.3 KB (3,351 bytes)
Types, interfaces, unions, generics, narrowing,
satisfies, a class with private fields and async code, with numbered comments explaining each part. Uses only erasable syntax, so Node.js can run it directly.- Checking a runtime or bundler handles modern TypeScript
- Teaching the building blocks of TypeScript
ES module that imports another (.mts)
sample-main.mts · 1.1 KB (1,103 bytes)
Imports a type with
import typeand values with an explicit.mtsextension fromsample-shapes.mts, and uses top-levelawait. Download both files to the same folder and runnode sample-main.mts.- Testing module resolution and `.ts` extensions in imports
- Checking `rewriteRelativeImportExtensions` output (`.mts` becomes `.mjs`)
Module that sample-main.mts imports
sample-shapes.mts · 879 bytes
Exports two types (a discriminated union of shapes) and two values. On its own it runs but prints nothing.
- Testing import resolution
- A minimal TypeScript ES module
Declaration file (.d.ts)
sample-types.d.ts · 1.1 KB (1,144 bytes)
Types only: a global variable, an overloaded function, a
declare modulefor an untyped package and an addition to the browser'sWindowinterface.- Testing tools that must treat `.d.ts` files differently
- Showing what a declaration file looks like
File with one deliberate type error
sample-type-error.ts · 1018 bytes
Clearly labelled at the top. It runs with
nodeand prints a wrong total, whiletsc --noEmitrejects it with error TS2345. Shows that runtimes don't check types.- Checking a CI step or editor reports type errors
- Demonstrating type stripping vs type checking
100 KB TypeScript file (CRLF)
sample-100kb.ts · 100 KB (102,400 bytes)
A typed table of the Roman numerals 1 to 3,999 and a parser that checks every one, saved with Windows (CRLF) line endings and padded with comments to exactly 102,400 bytes.
- Upload and size-limit tests
- Line-ending handling in tools and diffs
Ways to test with them
- Type stripping vs checking: run
sample-type-error.tswithnode, then withtsc --noEmit. The first prints a result; the second must fail with TS2345. - MIME types: put
sample-app.tsonline and check theContent-Typeyour server sends. If it'svideo/mp2t, browsers may try to play it instead of showing the code. - Module resolution: download
sample-main.mtsandsample-shapes.mtstogether and run them with Node.js, tsx, Deno and Bun, or compile them withtsc --rewriteRelativeImportExtensions --module nodenext. - Upload filters and limits: some filters treat
.tsas video.sample-100kb.tsis exactly 102,400 bytes, for testing a limit at the boundary.
Free to use for testing, teaching and demos, commercially or not, with no attribution needed. A link back to this page is always appreciated.
Put it online
Have a TypeScript file? Give it a link.
Drop a .ts file on 99helpers and it gets its own address in seconds. Opening the link shows the code as plain text in the browser, and it never runs, which is what you want for sharing source code.
Questions
TypeScript files, frequently asked
What is a .ts file?
Usually a TypeScript source file: JavaScript with type annotations, as plain text. It can also be an MPEG transport stream video, which is binary; open it in a text editor and you'll see which.
How do I run a .ts file?
With Node.js 22.18 or newer, run node file.ts. For files that use enums or other syntax Node.js can't strip, use npx tsx file.ts. Deno (deno run file.ts) and Bun (bun file.ts) run it directly too.
How do I convert a .ts file to .js?
Run npx tsc file.ts to write file.js next to it, or set up a tsconfig.json and run tsc for a whole project. Bundlers such as esbuild and Vite do the same while building.
Can a browser run TypeScript?
No. Browsers only run JavaScript, so TypeScript is compiled or bundled first. Opened directly, a .ts file shows as text, or is downloaded.
What's the difference between .ts and .d.ts?
A .ts file contains code that runs. A .d.ts declaration file contains only types that describe code living elsewhere, usually a JavaScript library, and produces no output.
What's the difference between .ts and .mts?
.mts is always an ES module and compiles to .mjs. A .ts file is an ES module or CommonJS depending on the nearest package.json, and compiles to .js. .cts is always CommonJS.
Does Node.js check types when it runs TypeScript?
No. It replaces the types with whitespace and runs the rest. Run tsc --noEmit to find type errors.
What is the MIME type of a TypeScript file?
None is registered. text/plain and application/typescript are common; video/mp2t belongs to the video format and makes browsers treat the file as video.
Is TypeScript a different language from JavaScript?
It's JavaScript with extra syntax for types. Any JavaScript file is valid TypeScript, and removing the types from TypeScript leaves JavaScript.
Related formats
Other file types explained
Keep going
Related
Sources
- Node.js documentation: Modules, TypeScript
- Node.js 22.18.0 release notes (type stripping on by default)
- Microsoft: Announcing TypeScript 7.0
- Deno documentation: TypeScript support
- Library of Congress: MPEG-2 Transport Stream
- SD Times: Microsoft introduces JavaScript 'superset' (2012)
Last reviewed 27 October 2026.