TypeScript es JavaScript con tipado estático. En 2026 es prácticamente obligatorio en proyectos profesionales: React, Angular, Next.js, NestJS y Node.js lo usan de forma nativa. Si quieres trabajar como desarrollador web o mejorar la calidad de tu código JavaScript, aprender TypeScript es el siguiente paso natural. En este tutorial aprenderás TypeScript desde cero, en español.

¿Qué es TypeScript y por qué usarlo?

  • Detección de errores en tiempo de compilación, no en producción
  • Mejor autocompletado en VS Code y otros editores
  • Código más legible y mantenible en equipos grandes
  • Compatible con todo el ecosistema JavaScript existente
  • Adoptado por React, Angular, Vue, Next.js, NestJS...

Instalación y configuración

npm install -g typescript
tsc --init  # Crea tsconfig.json

Configuración básica de tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "strict": true,
    "outDir": "./dist",
    "rootDir": "./src"
  }
}

Tipos básicos

let nombre: string = "Ana";
let edad: number = 30;
let activo: boolean = true;

// Arrays
let numeros: number[] = [1, 2, 3];
let nombres: Array<string> = ["Ana", "Luis"];

// Tuplas
let coordenada: [number, number] = [40.4168, -3.7038];

// Enums
enum Rol { Admin = "ADMIN", Editor = "EDITOR", Lector = "LECTOR" }
let miRol: Rol = Rol.Admin;

// Any, Unknown, Never
let desconocido: unknown = 42;  // mas seguro que any

Interfaces y tipos

interface Usuario {
    id: number;
    nombre: string;
    email: string;
    rol?: Rol;          // opcional
    readonly creado: Date;  // solo lectura
}

// type puede usar uniones, interface puede extenderse
type Resultado = "exito" | "error" | "pendiente";

interface Admin extends Usuario {
    permisos: string[];
}

const usuario: Usuario = {
    id: 1,
    nombre: "Maria",
    email: "maria@ejemplo.com",
    creado: new Date()
};

Funciones tipadas

function sumar(a: number, b: number): number {
    return a + b;
}

// Arrow function
const multiplicar = (a: number, b: number): number => a * b;

// Parametros opcionales y por defecto
function saludar(nombre: string, saludo: string = "Hola"): string {
    return `${saludo}, ${nombre}!`;
}

// Sobrecarga de funciones
function formatear(valor: string): string;
function formatear(valor: number): string;
function formatear(valor: string | number): string {
    return typeof valor === "number" ? valor.toFixed(2) : valor.trim();
}

Genéricos

// Funcion generica
function primero<T>(array: T[]): T | undefined {
    return array[0];
}

const num = primero([1, 2, 3]);        // tipo: number
const str = primero(["a", "b", "c"]); // tipo: string

// Interfaz generica
interface Respuesta<T> {
    datos: T;
    exito: boolean;
    mensaje: string;
}

// Restricciones de genericos
function obtenerPropiedad<T, K extends keyof T>(obj: T, clave: K): T[K] {
    return obj[clave];
}

const usuario = { nombre: "Ana", edad: 30 };
const nombre = obtenerPropiedad(usuario, "nombre");  // string

Clases en TypeScript

class Producto {
    private static _contador = 0;

    constructor(
        public readonly id: number = ++Producto._contador,
        public nombre: string,
        protected precio: number,
        private _stock: number = 0
    ) {}

    get stock(): number { return this._stock; }
    set stock(cantidad: number) {
        if (cantidad < 0) throw new Error("Stock no puede ser negativo");
        this._stock = cantidad;
    }

    toString(): string {
        return `[${this.id}] ${this.nombre} -- ${this.precio} EUR`;
    }
}

class ProductoDigital extends Producto {
    constructor(nombre: string, precio: number, public url: string) {
        super(undefined as any, nombre, precio, Infinity);
    }
}

Utilidades de TypeScript

interface Usuario { nombre: string; email: string; edad: number; }

type UsuarioParcial  = Partial<Usuario>;      // todas opcionales
type UsuarioCompleto = Required<UsuarioParcial>;// todas obligatorias
type SoloEmail       = Pick<Usuario, "email">;  // seleccionar campos
type SinEmail        = Omit<Usuario, "email">;  // excluir campos
type RolesUsuario    = Record<string, Rol[]>;   // clave-valor tipado

Preguntas frecuentes sobre TypeScript

¿TypeScript es mejor que JavaScript?

TypeScript no reemplaza a JavaScript, lo extiende con tipado estático. Sus ventajas: detección de errores en compilación (no en producción), mejor autocompletado y código más mantenible en equipos. Para proyectos pequeños o scripts sencillos, JavaScript puede ser suficiente. Para proyectos medianos o grandes con múltiples desarrolladores, TypeScript es prácticamente obligatorio en 2026.

¿Cuál es la diferencia entre interface y type en TypeScript?

Ambos definen la forma de un objeto, pero tienen diferencias importantes. interface puede extenderse con extends y es ideal para objetos y clases. type puede usar uniones (A | B), intersecciones (A & B) y tipos utilitarios complejos. La regla práctica: usa interface para definir contratos de objetos o clases, y type para uniones, aliases y tipos compuestos.

¿TypeScript funciona tanto en el frontend como en el backend?

Sí. En frontend se usa con React, Angular, Vue y Svelte. En backend, con Node.js (Express, NestJS, Fastify) y runtimes modernos como Deno o Bun que lo soportan nativamente sin compilación previa. Esto permite compartir tipos y lógica de validación entre frontend y backend, una gran ventaja en proyectos fullstack.

¿Cómo se compila TypeScript a JavaScript?

El compilador tsc transforma TypeScript a JavaScript puro que el navegador o Node.js pueden ejecutar. Lo configuras con tsconfig.json definiendo la versión de salida, los archivos a incluir y el directorio de destino. En desarrollo, herramientas como ts-node, tsx o esbuild permiten ejecutar TypeScript directamente sin compilar manualmente, lo que agiliza el flujo de trabajo.

Conclusión

TypeScript hace el código más robusto y el equipo más productivo. Una vez que lo adoptas, es difícil volver a JavaScript puro. Continúa aprendiendo con nuestro tutorial de React Hooks donde usamos TypeScript en todos los ejemplos.