Skip to content

📗 Clase 2 — Variables diferente (el tipo any)

TypeScript · 2026-07-11 · Carpeta: 02-Ejercicios/Variables_diferente ⬅️ Volver al índice de clases

🎯 Qué aprendí

  • Qué es el tipo any y por qué "desactiva" el chequeo de TypeScript.
  • El tipo unknown (el primo seguro de any) y cómo comprobar su tipo con typeof.
  • El tipo de retorno void (funciones que no devuelven nada).
  • El tipo never (funciones que nunca terminan / siempre lanzan error).
  • Por qué aparecen archivos extra (.js.map, .d.ts, .d.ts.map) al compilar.

📖 PARTE TEÓRICA

🅰️ El tipo any

any significa "cualquier cosa": una variable any puede guardar un texto, un número, un booleano… lo que sea, y TypeScript deja de revisarla.

typescript
let variableAny: any;
variableAny = "Hola, mundo!";   // ✅ string
variableAny = 42;               // ✅ number  (¡también válido!)
variableAny = true;             // ✅ boolean (¡también válido!)

console.log(`Variable any: ${variableAny}`);

Con un tipo normal, esto daría error. Con any, TS no se queja de ninguno:

typescript
let texto: string = "hola";
texto = 42;          // ❌ Error: number no es string

let libre: any = "hola";
libre = 42;          // ✅ Sin error (any acepta todo)
Tipo¿Revisa TypeScript?Qué acepta
string, number, boolean✅ SíSolo ese tipo
anyNoCualquier cosa

⚠️ any es como apagar TypeScript para esa variable. Vuelves a tener JavaScript "normal", sin la red de seguridad de los tipos. Por eso se recomienda evitarlo salvo casos puntuales (ej. datos externos que aún no sabes qué forma tienen).

🧪 Entrevista: ¿Por qué evitar any? Porque anula la principal ventaja de TS (detectar errores de tipo). Si todo es any, es como escribir JavaScript sin tipos. Alternativa más segura: unknown (lo veremos), que también acepta todo pero te obliga a comprobar el tipo antes de usarlo.

🔒 El tipo unknown (el any seguro)

unknown también acepta cualquier valor, pero con una diferencia clave: no te deja usarlo hasta que compruebes de qué tipo es. Es la alternativa recomendada a any.

typescript
let variableDesconocida: unknown;
variableDesconocida = 42;              // ✅ acepta cualquier cosa (como any)

// ❌ TS NO te deja usarla directo:
// console.log(variableDesconocida.toUpperCase());  // Error: es unknown

// ✅ primero compruebo el tipo con typeof:
if (typeof variableDesconocida === "string") {
    console.log(`Es texto: ${variableDesconocida}`);  // aquí TS ya sabe que es string
}
anyunknown
Acepta cualquier valor
Te deja usarlo sin comprobar✅ (peligroso)❌ (te obliga a comprobar)
Recomendado❌ Evitar✅ Preferir

💡 typeof es un operador de JavaScript que dice el tipo de un valor en tiempo de ejecución ("string", "number", "boolean"…). Dentro de un if (typeof x === ...), TypeScript "estrecha" (narrowing) el tipo y ya te deja usar la variable con seguridad.

🧪 Entrevista: ¿any vs unknown? Los dos aceptan todo, pero unknown es type-safe: obliga a verificar el tipo antes de usar el valor. any desactiva el chequeo por completo.

🕳️ void y never (tipos de retorno de funciones)

Se anotan después de los () de una función, para decir qué devuelve:

typescript
// void = "no devuelve nada" (solo hace algo, como imprimir)
function logMessage(message: string): void {
    console.log(`Mensaje: ${message}`);
}

// never = "nunca termina normalmente" (siempre lanza error o bucle infinito)
function throwError(message: string): never {
    throw new Error(message);
}
Tipo de retornoSignificaEjemplo típico
voidNo devuelve valor (hace algo y ya)Una función que solo hace console.log
neverNunca devuelve (rompe el flujo)Una función que siempre hace throw

📝 Diferencia fina: void sí termina (solo que sin devolver nada). never no llega a terminar normalmente — corta la ejecución con un error o se queda en bucle. No son lo mismo aunque las dos "no devuelvan un valor útil".

🧪 Entrevista: ¿Cuándo se usa never? En funciones que siempre lanzan excepción, o para marcar casos imposibles en un switch (chequeo de exhaustividad).

📂 Archivos extra al compilar (.js.map, .d.ts, .d.ts.map)

Al compilar con el tsconfig.json que genera tsc --init, aparecen más archivos que en la Clase 1. Cada uno viene de una opción del tsconfig.json:

ArchivoOpción que lo creaPara qué sirve
main.js(siempre)✅ Tu código en JS — lo que ejecuta node
main.js.map"sourceMap": trueDepurar: conecta el .js con el .ts
main.d.ts"declaration": trueDescribe los tipos (para publicar librerías)
main.d.ts.map"declarationMap": trueMapa que conecta el .d.ts con el .ts
main.ts ─tsc─▶ main.js        ← el importante
               main.js.map    ← mapa para depurar
               main.d.ts      ← los tipos
               main.d.ts.map  ← mapa de los tipos

💡 Para practicar solo importa main.js; los demás son ruido. Se pueden apagar poniendo sourceMap, declaration y declarationMap en false en el tsconfig.json.

📌 En la Clase 1 no aparecían porque aquel tsconfig.json era minimalista y no tenía esas opciones. El de tsc --init sí las trae activadas por defecto.


💻 PARTE PRÁCTICA

Archivos: 02-Ejercicios/Variables_diferente/main.ts y ejercicio-unknown.ts

bash
cd 02-Ejercicios/Variables_diferente
tsc && node main.js
# → Variable any: 42  ...

Incluye ejemplos de any, unknown + typeof, void y never (comentado). Verificado y corriendo. ✅

🧩 Más ejemplos (para afianzar)

any — el peligro real

typescript
let dato: any = "42";
let resultado = dato * 2;   // TS NO se queja... pero "42" * 2 da 84 por casualidad
let otro: any = "hola";
otro.metodoQueNoExiste();   // ❌ TS lo permite → ¡explota en tiempo de ejecución!

⚠️ Con any, el error no lo ves al compilar, sino cuando el programa ya está corriendo. Eso es justo lo que TypeScript quiere evitar.

unknown — comprobando varios tipos

typescript
function procesar(valor: unknown): string {
  if (typeof valor === "number") return `Número x10 = ${valor * 10}`;
  if (typeof valor === "string") return `Texto en mayúsculas = ${valor.toUpperCase()}`;
  if (typeof valor === "boolean") return valor ? "Sí" : "No";
  return "Tipo no soportado";
}

console.log(procesar(5));        // Número x10 = 50
console.log(procesar("hola"));   // Texto en mayúsculas = HOLA
console.log(procesar(true));     // Sí
console.log(procesar(null));     // Tipo no soportado

void — no confundir "no devuelve" con "devuelve undefined"

typescript
function saludar(nombre: string): void {
  console.log(`Hola, ${nombre}`);
  // no hay 'return' con valor → eso es void
}

let x = saludar("Ana");   // x vale undefined; no tiene sentido usarlo

never — el caso del switch exhaustivo

typescript
type Color = "rojo" | "verde";

function pintar(color: Color): string {
  switch (color) {
    case "rojo":  return "🔴";
    case "verde": return "🟢";
    default:
      // Si algún día agrego un color y olvido su case, TS avisa aquí.
      const imposible: never = color;
      return imposible;
  }
}

💡 never como "caso imposible" es un truco pro: obliga a que cubras todos los casos.


🏋️ EJERCICIOS CON SOLUCIÓN

Ejercicio 0 — Practicado en clase (ejercicio-unknown.ts) ✅

esTextoLargo(valor: unknown)true solo si es string de +5 letras · aMayusculas(valor: unknown) → MAYÚSCULAS si es texto, si no "No es texto". Patrón: comprobar con typeof primero y usar el valor dentro del if.

Ejercicio 1 — Longitud segura

Escribe longitud(valor: unknown): number que devuelva la longitud si es string, o -1 si no.

Ver solución
typescript
function longitud(valor: unknown): number {
  if (typeof valor === "string") return valor.length;
  return -1;
}
console.log(longitud("hola"));  // 4
console.log(longitud(42));      // -1

Terminal esperada:

zsh · longitud.ts
$ tsc longitud.ts
$ node longitud.js
4
-1

Ejercicio 2 — Función void

Escribe avisar(msg: string) que solo imprima Aviso: <msg>. ¿Qué tipo de retorno lleva?

Ver solución
typescript
function avisar(msg: string): void {   // void: no devuelve nada
  console.log(`Aviso: ${msg}`);
}
avisar("prueba");   // Aviso: prueba

Terminal esperada:

zsh · avisar.ts
$ tsc avisar.ts
$ node avisar.js
Aviso: prueba

Ejercicio 3 — Clasificar el tipo

Escribe tipoDe(valor: unknown): string que devuelva "es número", "es texto", "es booleano" o "desconocido" según el tipo.

Ver solución
typescript
function tipoDe(valor: unknown): string {
  if (typeof valor === "number") return "es número";
  if (typeof valor === "string") return "es texto";
  if (typeof valor === "boolean") return "es booleano";
  return "desconocido";
}
console.log(tipoDe(1));      // es número
console.log(tipoDe("a"));    // es texto
console.log(tipoDe(true));   // es booleano
console.log(tipoDe(null));   // desconocido

Terminal esperada:

zsh · tipoDe.ts
$ tsc tipoDe.ts
$ node tipoDe.js
es número
es texto
es booleano
desconocido

❓ Preguntas y respuestas (autoevaluación)

Léelas tapando la respuesta primero. Si aciertas, lo entendiste. ✅

1. ¿Cuál es la diferencia entre any y unknown?

Los dos aceptan cualquier valor. Pero any desactiva el chequeo de tipos (puedes usar el valor como quieras, arriesgado). unknown te obliga a comprobar el tipo (con typeof) antes de usarlo. unknown es la opción segura.

2. ¿Por qué este código falla?

typescript
let x: unknown = "hola";
console.log(x.toUpperCase());  // ❌ ?

Porque x es unknown y TS no sabe todavía si es un string. Hay que comprobarlo primero: if (typeof x === "string") { console.log(x.toUpperCase()); }

3. ¿Qué hace typeof y dónde se usa?

Es un operador de JavaScript que devuelve el tipo de un valor en ejecución ("string", "number", "boolean", "undefined", "object"…). Se usa dentro de un if para que TS "estreche" (narrowing) el tipo y te permita usar la variable con seguridad.

4. ¿Qué tipo de retorno pondrías a una función que solo imprime en consola?

void, porque no devuelve ningún valor útil, solo ejecuta una acción.

5. ¿Y a una función que siempre lanza un throw new Error(...)?

never, porque nunca llega a terminar normalmente (corta el flujo con el error).

6. ¿void y never son lo mismo?

No. void termina pero sin devolver valor. never no termina (lanza error o bucle infinito). Una función void sí completa su ejecución; una never, no.

7. Si compilo y aparecen main.d.ts y main.js.map, ¿hice algo mal?

No. Los generan las opciones declaration, sourceMap y declarationMap del tsconfig.json (activadas por tsc --init). Para practicar solo necesitas main.js.

8. ¿Cuándo SÍ tiene sentido usar any?

En casos puntuales: datos externos cuya forma aún no conoces, o migrando código viejo de JS poco a poco. Aun así, casi siempre unknown es mejor opción.

📎 Apuntes relacionados

➡️ Siguiente

Clase 3 — Arrays y tuplas (cómo tipar listas de datos).