Menu

Cómo ejecutar un archivo TypeScript: tsc, Node.js, tsx, ts-node

Cinco formas de ejecutar un archivo .ts: compilar con tsc y ejecutar el JavaScript, ejecutarlo directamente con node file.ts (type stripping), usar tsx o ts-node, o usar Deno y Bun. Cuáles comprueban tipos, qué sintaxis admite cada una y cuál elegir.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Un archivo TypeScript no se puede ejecutar tal cual, porque los navegadores y los motores de JavaScript no entienden las anotaciones de tipo. Algo tiene que quitar antes los tipos. Ese algo es o bien el compilador de TypeScript (tsc), que además comprueba los tipos, o una herramienta más rápida que solo los elimina. La forma más rápida de ejecutar el código de esta página es el botón Run:

Salida:

[x] Install TypeScript
[ ] Run a .ts file

Todos los bloques ejecutables de esta documentación funcionan igual: TypeScript 7 comprueba los tipos del código con strict activado, y solo se ejecuta si no hay errores de tipo. Para experimentos más largos, el playground de TypeScript es el mismo editor en una página propia. El resto de esta página trata de ejecutar archivos .ts en tu propio equipo.

Las opciones de un vistazo

ComandoComprueba tiposNecesita un paso de buildAdmite enum, namespace, parameter properties
npx tsc y luego node dist/index.jsSíSíSí
node index.ts (Node.js 22.18+, 23.6+)NoNoNo
npx tsx index.tsNoNoSí
npx ts-node index.tsSíNoSí, pero no con TypeScript 7
deno run index.tsNo (lo hace deno check)NoSí
bun index.tsNoNoSí

La columna que sorprende es la primera: la mayoría de las opciones rápidas ejecutan código que contiene errores de tipo. Un proyecto típico ejecuta el código con una de ellas y lanza tsc --noEmit por separado, en el editor y en CI, para detectar los errores.

Compilar con tsc y ejecutar con Node

Es el enfoque que funciona en todas partes y lo comprueba todo. Con TypeScript instalado en el proyecto y un tsconfig.json que fija "rootDir": "./src" y "outDir": "./dist":

npx tsc
node dist/index.js

tsc comprueba los tipos de todos los archivos y después escribe los archivos .js en dist. Para un solo archivo sin proyecto, pasa el nombre del archivo. Entonces usa las opciones por defecto y escribe index.js junto a index.ts:

npx tsc index.ts
node index.js

(Si la carpeta tiene un tsconfig.json, tsc rechaza los nombres de archivo con error TS5112; ejecuta npx tsc sin más, o añade --ignoreConfig.)

Por defecto tsc escribe el JavaScript aunque haya errores de tipo, así que node puede ejecutar un programa que no pasó la comprobación. Añade "noEmitOnError": true a la configuración para evitarlo, o encadena los comandos en un script para que el segundo paso solo se ejecute si el primero tiene éxito:

{
    "scripts": {
        "build": "tsc",
        "start": "tsc && node dist/index.js"
    }
}

Durante el desarrollo, npx tsc --watch recompila cada vez que guardas.

Ejecutar TypeScript directamente con Node.js

Las versiones actuales de Node.js ejecutan archivos .ts por sí mismas:

node index.ts

Node elimina las anotaciones de tipo, sustituyéndolas por espacios para que los números de línea de las trazas de error sigan coincidiendo, y ejecuta lo que queda. Está activado por defecto desde Node.js 23.6.0 y 22.18.0, no imprime ningún aviso desde 24.3.0 y 22.18.0, y se marcó como estable en Node.js 24.12.0 y 25.2.0. Las versiones anteriores que tienen la funcionalidad (de 22.6 a 22.17, y de 23.0 a 23.5) necesitan el flag: node --experimental-strip-types index.ts.

Vienen con cuatro reglas:

  • Sin comprobación de tipos. Un archivo con const age: number = "forty" se ejecuta e imprime forty.
  • Solo sintaxis borrable. Todo lo que tenga que convertirse en código JavaScript, en lugar de desaparecer, se rechaza: enum, los bloques namespace con código de ejecución, las parameter properties del constructor como constructor(private name: string) y los alias import x = require(). Node se detiene con SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript enum is not supported in strip-only mode.
  • tsconfig.json se ignora. Opciones como paths o target no tienen efecto.
  • Los imports necesitan nombres de archivo reales. Escribe import { add } from "./math.ts", con la extensión, y marca los imports solo de tipos con type: import { add, type Pair } from "./math.ts". Sin type, Node busca un export de ejecución llamado Pair y falla con SyntaxError: The requested module './math.ts' does not provide an export named 'Pair'.

Dos opciones del compilador hacen que tsc aplique las mismas reglas, para que el editor te avise antes que Node: "erasableSyntaxOnly": true informa de error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. en un enum, y "verbatimModuleSyntax": true exige la palabra type en los imports solo de tipos. Para seguir escribiendo extensiones .ts en los imports y aun así compilar con tsc, añade "rewriteRelativeImportExtensions": true, que convierte ./math.ts en ./math.js en la salida.

Node.js 24 también tiene --experimental-transform-types, que genera código para los enums y las parameter properties en lugar de rechazarlos. Imprime un ExperimentalWarning, y Node.js 26 eliminó el flag, así que no construyas nada sobre él.

Este bloque usa dos funcionalidades que node index.ts rechaza. Aquí se ejecuta porque el editor lo compila con el compilador de TypeScript, que genera JavaScript para las dos:

La versión borrable del mismo código usa un objeto const y un campo normal, que Node puede ejecutar tal cual:

tsx

tsx ejecuta un archivo TypeScript en un solo paso, sin configuración y sin restricciones de sintaxis:

npm install --save-dev tsx
npx tsx index.ts
npx tsx watch index.ts   # rerun on every change

Transforma el código con esbuild, así que los enums, los namespaces y las parameter properties funcionan, y los imports sin extensión se resuelven como en un bundler. Igual que el type stripping de Node, no comprueba tipos. Es la opción habitual para scripts, servidores de desarrollo y tests en versiones de Node.js anteriores al type stripping, o cuando el código usa sintaxis que Node rechaza.

ts-node

ts-node fue durante años la forma estándar de ejecutar TypeScript en Node.js, y sigue siendo lo que usan muchos tutoriales y proyectos antiguos (npx ts-node index.ts, node -r ts-node/register). Comprueba tipos por defecto, usando la API JavaScript del compilador de TypeScript.

Esa API es justo lo que TypeScript 7 no incluye: su compilador es un programa nativo, y el paquete typescript 7 no expone ninguna API del compilador a JavaScript. Con TypeScript 7 instalado, ts-node falla antes de ejecutar nada:

TypeError: Cannot read properties of undefined (reading 'fileExists')
    at readConfig (/project/node_modules/ts-node/dist/configuration.js:91:33)

La última versión de ts-node, la 10.9.2, es de diciembre de 2023. Para código nuevo usa tsx o node index.ts. Una configuración existente que depende de ts-node sigue funcionando si el proyecto se queda en TypeScript 6 (npm install --save-dev typescript@6) y tiene un tsconfig.json, aunque sea un {} vacío. Sin él, ts-node recurre a valores por defecto integrados que incluyen la resolución de módulos node10 que TypeScript 6 marcó como obsoleta, y npx ts-node index.ts termina sin ejecutar el archivo ni imprimir ningún error.

Deno y Bun

Los dos runtimes tratan TypeScript como un tipo de archivo de primera clase:

deno run index.ts    # runs without checking
deno check index.ts  # type-checks, reports errors, runs nothing

bun index.ts         # runs without checking

Ninguno necesita tener typescript instalado ni un tsconfig.json, y ambos admiten enum y las demás funcionalidades no borrables. Deno incluye su propia copia del compilador de TypeScript para deno check. Bun solo quita los tipos, así que en un proyecto con Bun sigues instalando typescript y ejecutando tsc --noEmit para encontrar errores de tipo.

Los errores de tipo solo detienen el programa con tsc

Solo las vías que ejecutan tsc primero se niegan a ejecutar un programa con errores de tipo. El editor de esta página es una de ellas, así que este bloque se detiene en el compilador:

index.ts(6,21): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

Guardado en un archivo y ejecutado con node index.ts, npx tsx index.ts o bun index.ts, el mismo código se ejecuta e imprime 12, porque 3 * "4" convierte el string. Por eso conviene mantener tsc --noEmit en el flujo aunque sea una herramienta más rápida la que ejecuta el código:

{
    "scripts": {
        "dev": "tsx watch src/index.ts",
        "typecheck": "tsc --noEmit"
    }
}

¿Cuál deberías usar?

  • Para aprender o hacer una prueba rápida: el botón Run de estas páginas, o el playground.
  • Un script o una herramienta pequeña en un Node.js actual: node index.ts, con erasableSyntaxOnly en la configuración para que el editor marque lo que Node rechazaría.
  • Cualquier proyecto de Node.js, con cualquier sintaxis: tsx para ejecutar, tsc --noEmit para comprobar.
  • Una librería o cualquier cosa que publiques: tsc, porque también escribe los archivos .d.ts que necesitan tus usuarios.
  • Código de frontend: tu bundler o framework (Vite, Next.js, Angular CLI) ejecuta el TypeScript por ti; añade tsc --noEmit para la comprobación.

Preguntas frecuentes

¿Cómo ejecuto un archivo TypeScript?

La forma clásica son dos pasos: npx tsc compila .ts a .js y luego node dist/index.js ejecuta la salida. En Node.js 22.18 o 23.6 y posteriores también puedes ejecutar node index.ts directamente, siempre que el archivo solo use sintaxis de tipos que se pueda borrar. npx tsx index.ts ejecuta cualquier archivo TypeScript en un solo paso.

¿Puede Node.js ejecutar TypeScript directamente?

Sí. Desde Node.js 23.6 y 22.18, node file.ts funciona sin flags: Node quita las anotaciones de tipo y ejecuta el resto. No comprueba tipos, ignora tsconfig.json y rechaza la sintaxis que necesita generar código, como enum, namespace con código de ejecución y las parameter properties del constructor.

¿Funciona ts-node con TypeScript 7?

No. ts-node llama a la API JavaScript del compilador, que el paquete typescript 7 no ofrece, así que falla al arrancar (Cannot read properties of undefined (reading 'fileExists')). Su última versión es la 10.9.2, de diciembre de 2023. Usa tsx, el type stripping propio de Node, o mantén ts-node con TypeScript 6.

¿Qué diferencia hay entre tsx y ts-node?

tsx solo quita los tipos (con esbuild) y ejecuta el resultado, así que arranca rápido y nunca informa de errores de tipo. ts-node comprueba tipos por defecto con el compilador de TypeScript, lo que lo hace más lento y lo ata a la API JavaScript del compilador. La mayoría de proyectos combina ahora tsx o node file.ts para ejecutar con tsc --noEmit para comprobar.

¿Hay un sandbox de TypeScript online?

Sí. Los bloques de código de estas páginas de documentación y el playground de TypeScript de Coddy compilan tu código con TypeScript 7 y lo ejecutan, mostrando los errores del compilador o la salida del programa. El TypeScript Playground oficial de typescriptlang.org muestra el JavaScript generado y los errores.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR