Saltar al contenido principal
Volver atrás

TypeScript #7: Unknown vs Any & Never

#typescript #unknown #safety

Por qué 'any' es el diablo y 'unknown' tu mejor amigo. Aprendiendo a escribir código seguro a prueba de bombas.

En TypeScript existen dos “Tipos Superiores” (Top Types) que pueden contener cualquier valor: any y unknown. Aunque parecen similares, son opuestos en filosofía.

Y luego está never, el tipo que no contiene nada. Vamos a verlos.

1. any: El enemigo silencioso 😈

any es básicamente “desactivar TypeScript”. Cuando asignas algo a any, el compilador deja de comprobar nada. Puedes acceder a propiedades que no existen, llamar a la variable como una función, etc.

typescript
let peligro: any = "Hola mundo";

// TypeScript NO se queja de nada de esto:
peligro.foo.bar.baz(); 
peligro();
const x: number = peligro;

// ...pero todo fallará en ejecución 💥
Evita any a toda costa

Usar any contagia tu código. Si una función devuelve any, esa falta de seguridad se propaga. Úsalo solo cuando estés migrando código JS antiguo o sea 100% imposible saber el tipo (y aun así, prefiere unknown).

2. unknown: La alternativa segura 🛡️

unknown es como any: acepta cualquier valor. PERO (y es un gran pero) no te deja hacer nada con él hasta que compruebes qué es.

Te obliga a usar Narrowing (lo que vimos en el Cap. #6) antes de usarlo.

typescript
let seguro: unknown = "Hola mundo";

// Error: Object is of type 'unknown'.
// seguro.toUpperCase(); 

// La forma correcta: Comprobar primero
if (typeof seguro === "string") {
// Ahora TS sabe que es string
console.log(seguro.toUpperCase());
}

Esto es ideal para respuestas de APIs externas o JSON.parse(), donde realmente no sabes qué vendrá, pero quieres manejarlo de forma segura.

3. never: Lo imposible 🚫

never es el tipo para valores que nunca pueden ocurrir. Es el tipo de retorno de una función que lanza un error siempre (y por tanto nunca retorna) o un bucle infinito.

typescript
function error(mensaje: string): never {
throw new Error(mensaje);
}
// Esta función nunca devuelve "undefined" ni nada, 
// su ejecución nunca termina exitosamente.

Exhaustiveness Checking (El truco pro)

El uso más potente de never es asegurarte de que has cubierto todos los casos posibles en un switch o ion.

typescript
type Estado = "Cargando" | "Exito" | "Error";

function getMensaje(s: Estado) {
switch (s) {
  case "Cargando": return "⏳";
  case "Exito": return "✅";
  case "Error": return "❌";
  default:
    // Si mañana añades "Inactivo" a Estado, 
    // TS marcará error aquí porque "s" no sería never.
    const _exhaustiveCheck: never = s;
    return _exhaustiveCheck;
}
}

Si en el futuro alguien añade | "Inactivo" al tipo Estado y olvida actualizar el switch, TypeScript lanzará un error en tiempo de compilación diciendo que Type 'string' is not assignable to type 'never'. ¡Magia! ✨

4. Ejercicio: Domando lo Desconocido

Vamos a poner en práctica unknown. Tienes una función que recibe un dato desconocido. Para usarlo de forma segura, necesitarás aplicar lo aprendido en el capítulo anterior (Type Guards).

Tu misión:

  1. Comprobar si es un string.
  2. Si lo es, devolverlo en MAYÚSCULAS.
  3. Si NO lo es, lanzar un error diciendo exactamente: "No es texto".

¡Con esto cerramos el bloque de tipos avanzados de seguridad! Ahora tu código será mucho más robusto. 🛡️

Resumen

  • any: “Me da igual todo, déjame en paz”. (Inseguro, evítalo).
  • unknown: “No sé qué es esto, así que te obligaré a comprobarlo”. (Seguro).
  • never: “Esto no debería pasar nunca”. (Útil para asegurar lógica exhaustiva).