Variables: let, const y por qué var ya no se usa
Tres palabras clave para guardar valores en memoria. Aprende cuándo usar cada una, qué significa alcance de bloque, y cómo TypeScript te ayuda a no romper cosas que no debías tocar.
¿Qué es una variable?
Una variable es un nombre que apunta a un valor en memoria. En lugar de repetir el dato cada vez, lo guardas una vez y lo reutilizas con su nombre.
// Sin variable: repites el valor
console.log("Hola, Fernando");
console.log("Hola, Fernando");
// Con variable: lo guardas una vez
const nombre = "Fernando";
console.log(`Hola, ${nombre}`);
console.log(`Adiós, ${nombre}`);// TypeScript infiere el tipo automáticamente
const nombre: string = "Fernando";
const edad: number = 38;
const activo: boolean = true;
console.log(`${nombre}, ${edad} años`);Hola, Fernando
Adiós, Fernandolet — cuando el valor va a cambiar
Usa let para variables cuyo valor cambia con el tiempo: contadores, banderas, acumuladores, lo que se actualiza dentro de un bucle.
let contador = 0;
for (let i = 0; i < 5; i++) {
contador += i;
}
console.log(contador); // 10
// Reasignar: válido
contador = 100;let contador: number = 0;
for (let i = 0; i < 5; i++) {
contador += i;
}
console.log(contador); // 10
// Cambiar a otro tipo: error de compilación
contador = "diez"; // ❌ Type 'string' is not assignable to type 'number'10Si después de escribir el código nunca reasignas la variable, cámbiala a const. Es la regla más simple para escribir código predecible.
const — la opción por defecto
const declara una referencia inmutable: la variable no puede apuntar a otro valor. Pero ojo: si el valor es un objeto o array, su contenido sí puede cambiar.
const PI = 3.14159;
PI = 3; // ❌ TypeError: Assignment to constant variable
// Pero con objetos y arrays:
const usuario = { nombre: "Ana", edad: 25 };
usuario.edad = 26; // ✅ El objeto muta, la referencia no cambia
usuario = {}; // ❌ Error: no puedes apuntar a otro objeto
const nums = [1, 2, 3];
nums.push(4); // ✅ El array muta
nums = [5]; // ❌ Errorconst PI = 3.14159; // tipo: 3.14159 (literal exacto con const)
const usuario = { nombre: "Ana", edad: 25 };
// tipo inferido: { nombre: string; edad: number }
usuario.edad = 26; // ✅
usuario.activo = true; // ❌ Property 'activo' does not exist on type...
// Para hacer un objeto realmente inmutable:
const CONFIG = { host: "localhost", port: 3000 } as const;
CONFIG.port = 8080; // ❌ Cannot assign to 'port' because it is a read-only propertyvar — por qué ya no se usa
var existía antes de ES6 (2015). Tiene dos problemas graves que let y const resuelven:
| Característica | var | let / const |
|---|---|---|
| Alcance | Función completa | Bloque { } |
| Hoisting | Se eleva como undefined | TDZ — error si accedes antes |
| Re-declarar | Permitido (bug silencioso) | Error de sintaxis |
Si ves var en código antiguo, refactoriza con cuidado — puede haber bugs silenciosos ocultos en el comportamiento del hoisting. No uses var en código nuevo.
Alcance de bloque
let y const viven dentro del bloque {} donde fueron declaradas. Fuera de ese bloque, no existen.
let x = 10;
if (true) {
let y = 20;
console.log(x); // ✅ 10
console.log(y); // ✅ 20
}
console.log(x); // ✅ 10
console.log(y); // ❌ ReferenceError: y is not definedTypeScript: tipos en variables
En TypeScript puedes (y normalmente no debes) anotar el tipo. La regla: deja que TypeScript infiera, anota solo cuando quieras forzar un tipo más amplio o más estrecho.
// 1. Inferencia: TS deduce el tipo del valor inicial
let ciudad = "Madrid"; // inferido: string
let intentos = 0; // inferido: number
const activos = ["Ana", "Luis"]; // inferido: string[]
// 2. Anotación explícita: cuando importa
let usuario: string | null = null;
const max: number = 100;
// 3. const + literal = tipo literal exacto
const rol = "admin"; // tipo: "admin" (literal)
let rol2 = "admin"; // tipo: string (más amplio)Una variable const rol = "admin" en TypeScript tiene el tipo "admin", no string. Esto es la base de los discriminated unions que verás más adelante.
Reglas de oro
- Usa
constpor defecto. Es la opción más segura: el lector sabe que el nombre nunca cambia. - Cambia a
letsolo si reasignas. Contadores, acumuladores, banderas que cambian dentro de un bloque. - Nunca uses
var. En código nuevo no hay razón. Si lo ves en código viejo, refactoriza con cuidado alet. - Nombres en
camelCase.nombreUsuario, nonombre_usuarioniNombreUsuario. - Constantes globales en
UPPER_SNAKE.MAX_REINTENTOS,API_URL.
Practica lo que acabas de leer
5 ejercicios cortos en el editor. La mayoría se resuelven en menos de 5 minutos.