Apariencia
📗 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
anyy por qué "desactiva" el chequeo de TypeScript. - El tipo
unknown(el primo seguro deany) y cómo comprobar su tipo contypeof. - 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 |
any | ❌ No | Cualquier cosa |
⚠️
anyes 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 esany, 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
}any | unknown | |
|---|---|---|
| Acepta cualquier valor | ✅ | ✅ |
| Te deja usarlo sin comprobar | ✅ (peligroso) | ❌ (te obliga a comprobar) |
| Recomendado | ❌ Evitar | ✅ Preferir |
💡
typeofes un operador de JavaScript que dice el tipo de un valor en tiempo de ejecución ("string","number","boolean"…). Dentro de unif (typeof x === ...), TypeScript "estrecha" (narrowing) el tipo y ya te deja usar la variable con seguridad.
🧪 Entrevista: ¿
anyvsunknown? Los dos aceptan todo, perounknownes type-safe: obliga a verificar el tipo antes de usar el valor.anydesactiva 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 retorno | Significa | Ejemplo típico |
|---|---|---|
void | No devuelve valor (hace algo y ya) | Una función que solo hace console.log |
never | Nunca devuelve (rompe el flujo) | Una función que siempre hace throw |
📝 Diferencia fina:
voidsí termina (solo que sin devolver nada).neverno 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 unswitch(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:
| Archivo | Opción que lo crea | Para qué sirve |
|---|---|---|
main.js | (siempre) | ✅ Tu código en JS — lo que ejecuta node |
main.js.map | "sourceMap": true | Depurar: conecta el .js con el .ts |
main.d.ts | "declaration": true | Describe los tipos (para publicar librerías) |
main.d.ts.map | "declarationMap": true | Mapa 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 poniendosourceMap,declarationydeclarationMapenfalseen eltsconfig.json.
📌 En la Clase 1 no aparecían porque aquel
tsconfig.jsonera minimalista y no tenía esas opciones. El detsc --initsí 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 soportadovoid — 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 usarlonever — 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;
}
}💡
nevercomo "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)); // -1Terminal esperada:
$ tsc longitud.ts
$ node longitud.js
4
-1Ejercicio 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: pruebaTerminal esperada:
$ tsc avisar.ts
$ node avisar.js
Aviso: pruebaEjercicio 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)); // desconocidoTerminal esperada:
$ 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
anydesactiva el chequeo de tipos (puedes usar el valor como quieras, arriesgado).unknownte obliga a comprobar el tipo (contypeof) antes de usarlo.unknownes la opción segura.
2. ¿Por qué este código falla?
typescript
let x: unknown = "hola";
console.log(x.toUpperCase()); // ❌ ?Porque
xesunknowny 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 unifpara 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.
voidtermina pero sin devolver valor.neverno termina (lanza error o bucle infinito). Una funciónvoidsí completa su ejecución; unanever, no.
7. Si compilo y aparecen main.d.ts y main.js.map, ¿hice algo mal?
No. Los generan las opciones
declaration,sourceMapydeclarationMapdeltsconfig.json(activadas portsc --init). Para practicar solo necesitasmain.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
unknownes mejor opción.
📎 Apuntes relacionados
➡️ Siguiente
Clase 3 — Arrays y tuplas (cómo tipar listas de datos).