Skip to content

Instalación y tsconfig ​

Para usar TypeScript necesitas el compilador y un archivo de configuración que le diga cómo revisar y compilar tu código. En esta lección instalarás TypeScript en un proyecto, entenderás las opciones más importantes del tsconfig.json y conocerás las formas modernas de ejecutar TS: tsx, Vite y el Playground.

Concepto ​

El compilador de TypeScript se llama tsc (TypeScript Compiler). Hace dos trabajos:

  1. Revisar tipos (type checking): encuentra errores.
  2. Emitir JavaScript: genera los archivos .js sin tipos.

El archivo tsconfig.json es como el panel de control del compilador: qué archivos revisar, qué tan estricto ser, a qué versión de JavaScript compilar y dónde dejar el resultado.

Instalación paso a paso ​

Se recomienda instalar TypeScript por proyecto (como dependencia de desarrollo), no de forma global. Así cada proyecto fija su versión.

bash
# 1. Crea la carpeta y el package.json
mkdir mi-proyecto-ts
cd mi-proyecto-ts
npm init -y

# 2. Instala TypeScript como dependencia de desarrollo
npm i -D typescript

# 3. Verifica la versión
npx tsc --version

# 4. Genera un tsconfig.json con valores recomendados
npx tsc --init

npx ejecuta el tsc instalado en node_modules. Si necesitas repasar npm, revisa npm y package.json.

Primer archivo y compilación ​

Crea src/index.ts:

ts
// src/index.ts
interface Producto {
  nombre: string;
  precio: number;
}

const productos: Producto[] = [
  { nombre: 'Mouse', precio: 349 },
  { nombre: 'Teclado', precio: 1299 }
];

// Sumamos los precios: TS sabe que p.precio es number
const total = productos.reduce((suma, p) => suma + p.precio, 0);

console.log(`Total: $${total}`);

Compila y ejecuta:

bash
npx tsc            # revisa todo el proyecto y genera los .js en outDir
node dist/index.js # ejecuta el JavaScript generado

Comandos útiles de tsc:

bash
npx tsc --watch    # recompila cada vez que guardas
npx tsc --noEmit   # solo revisa tipos, no genera archivos (muy usado en CI)

Agrégalos a tu package.json:

json
{
  "scripts": {
    "build": "tsc",
    "dev": "tsc --watch",
    "typecheck": "tsc --noEmit"
  }
}

El tsconfig.json explicado ​

npx tsc --init genera un archivo enorme lleno de comentarios. Este es un tsconfig.json limpio y moderno con las opciones que de verdad importan:

json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "lib": ["ES2022"],
    "rootDir": "src",
    "outDir": "dist",
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src"]
}

Veamos qué hace cada una.

target ​

La versión de JavaScript que se genera. Con ES2022, TS deja tal cual async/await, clases, ?. y ??. Con un target viejo como ES5, TS reescribe todo eso en código antiguo (más largo). Hoy, navegadores modernos y Node 18+ soportan ES2022 sin problema.

module ​

Qué sistema de módulos usa el JavaScript generado:

  • NodeNext: para proyectos de Node; respeta "type": "module" del package.json.
  • ESNext: deja los import/export intactos; ideal cuando un bundler (Vite) procesa el código.
  • CommonJS: genera require y module.exports (proyectos Node antiguos).

moduleResolution ​

Cómo TS encuentra los archivos que importas.

  • NodeNext: igual que Node moderno. Exige extensiones en imports relativos: import { x } from './utils.js' (sí, .js aunque el archivo sea .ts).
  • Bundler: para proyectos con Vite, webpack o similares. Permite imports sin extensión.

Regla rápida

Node puro → module y moduleResolution en NodeNext. Frontend con Vite → module: "ESNext" y moduleResolution: "Bundler".

lib ​

Qué APIs "integradas" conoce TS. ES2022 incluye Array.prototype.at, Object.hasOwn, etc. Si trabajas en el navegador agrega "DOM" y "DOM.Iterable" para tener document, HTMLElement, fetch y compañía.

json
"lib": ["ES2022", "DOM", "DOM.Iterable"]

rootDir y outDir ​

  • rootDir: dónde está tu código fuente (src).
  • outDir: dónde se guarda el JavaScript compilado (dist).

Así src/utils/fecha.ts termina en dist/utils/fecha.js, manteniendo la estructura. Agrega dist a tu .gitignore.

strict ​

La opción más importante. Activa un paquete de revisiones estrictas, entre ellas:

  • strictNullChecks: null y undefined no se pueden usar como si fueran otro tipo.
  • noImplicitAny: si TS no puede inferir un tipo, te obliga a escribirlo en vez de usar any en silencio.
  • strictFunctionTypes, strictPropertyInitialization y otras.
ts
// Con strict: true
function saludar(nombre) {
  //             ❌ Parameter 'nombre' implicitly has an 'any' type.
  return 'Hola ' + nombre;
}

const input = document.querySelector('input');
input.value = 'hola';
// ❌ 'input' is possibly 'null'.

Buena práctica

Activa siempre "strict": true en proyectos nuevos. Sin él, TypeScript deja pasar muchos de los errores que justamente quieres atrapar.

noUncheckedIndexedAccess ​

No viene dentro de strict, pero es muy recomendable. Hace que acceder a un array o diccionario por índice devuelva T | undefined, porque el elemento podría no existir:

ts
const colores = ['rojo', 'verde'];

const tercero = colores[2];    // tipo: string | undefined
tercero.toUpperCase();
// ❌ 'tercero' is possibly 'undefined'.

// Debes comprobarlo antes
if (tercero) {
  console.log(tercero.toUpperCase()); // ✅
}

Otras opciones útiles ​

  • esModuleInterop: permite import express from 'express' con librerías CommonJS.
  • skipLibCheck: no revisa los .d.ts de node_modules (compila más rápido y evita errores ajenos).
  • forceConsistentCasingInFileNames: evita bugs entre Windows (no distingue mayúsculas) y Linux (sí las distingue).
  • include: qué carpetas revisa TS.

Ejecutar TS directamente con tsx ​

Compilar y luego ejecutar es lento para desarrollar. tsx ejecuta archivos .ts al vuelo:

bash
npm i -D tsx

npx tsx src/index.ts          # ejecuta una vez
npx tsx watch src/index.ts    # reinicia al guardar
json
{
  "scripts": {
    "dev": "tsx watch src/index.ts",
    "typecheck": "tsc --noEmit",
    "build": "tsc"
  }
}

Error común

tsx (y Vite, esbuild o Node con su modo de quitar tipos) no revisa tipos: solo los borra y ejecuta. Tu código puede correr aunque tenga errores de tipo. Por eso siempre conviene tener el script typecheck con tsc --noEmit y correrlo antes de subir cambios.

Proyecto de frontend con Vite + TypeScript ​

Para frontend lo más práctico es Vite, que ya trae TypeScript configurado:

bash
npm create vite@latest mi-app -- --template vanilla-ts
cd mi-app
npm install
npm run dev

Plantillas útiles: vanilla-ts, react-ts, vue-ts, svelte-ts.

Vite genera un tsconfig.json pensado para el navegador (resumido):

json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "lib": ["ES2022", "DOM", "DOM.Iterable"],
    "strict": true,
    "noEmit": true,
    "skipLibCheck": true
  },
  "include": ["src"]
}

Fíjate en "noEmit": true: en Vite, tsc solo revisa tipos y es Vite quien genera el JavaScript final. Por eso el script de build suele ser tsc && vite build (primero revisa, luego empaqueta).

TypeScript Playground ​

Para experimentar sin instalar nada, usa el TypeScript Playground: https://www.typescriptlang.org/play. Escribes TS a la izquierda y ves el JS generado a la derecha, con los errores marcados. Es perfecto para probar los ejemplos de este curso.

Ejercicios ​

  1. Crea un proyecto con npm init -y, instala TypeScript y genera un tsconfig.json. Configura rootDir: "src" y outDir: "dist".
  2. Agrega a package.json tres scripts: dev (con tsx watch), typecheck y build.
  3. ¿Qué opciones de lib, module y moduleResolution usarías para un proyecto de navegador con Vite?
  4. Con noUncheckedIndexedAccess activo, corrige este código:
ts
const precios = [100, 250, 80];
const primero = precios[0];
console.log(primero.toFixed(2));
Ver solución
  1. y 2.
bash
mkdir ejercicio-ts && cd ejercicio-ts
npm init -y
npm i -D typescript tsx
npx tsc --init
json
{
  "scripts": {
    "dev": "tsx watch src/index.ts",
    "typecheck": "tsc --noEmit",
    "build": "tsc"
  }
}

En tsconfig.json: "rootDir": "src" y "outDir": "dist".

  1. lib: ["ES2022", "DOM", "DOM.Iterable"], module: "ESNext", moduleResolution: "Bundler".

ts
const precios = [100, 250, 80];
const primero = precios[0]; // number | undefined

if (primero !== undefined) {
  console.log(primero.toFixed(2));
}

// O con un valor por defecto
console.log((precios[0] ?? 0).toFixed(2));

Resumen ​

  • Instala TypeScript por proyecto: npm i -D typescript; genera la config con npx tsc --init.
  • tsc revisa tipos y emite JS; tsc --noEmit solo revisa.
  • strict: true siempre; noUncheckedIndexedAccess es un gran extra.
  • target define la versión de JS generada; module y moduleResolution dependen de si usas Node (NodeNext) o un bundler (ESNext + Bundler).
  • Agrega DOM a lib para código de navegador.
  • tsx y Vite ejecutan TS rápido pero no revisan tipos: complementa con tsc --noEmit.
  • El Playground es ideal para experimentar.

Siguiente: Tipos básicos

Academia Web — aprende, copia y construye.