A TypeScript existeixen dos “Tipus Superiors” (Top Types) que poden contenir qualsevol valor: any i unknown. Encara que semblen similars, són oposats en filosofia.
I després està never, el tipus que no conté res. Anem a veure’ls.
1. any: L’enemic silenciós 😈
any és bàsicament “desactivar TypeScript”. Quan assignes alguna cosa a any, el compilador deixa de comprovar res. Pots accedir a propietats que no existeixen, cridar a la variable com una funció, etc.
let perill: any = "Hola món";
// TypeScript NO es queixa de res d'això:
perill.foo.bar.baz();
perill();
const x: number = perill;
// ...però tot fallarà en execució 💥let perill: any = "Hola món";
// TypeScript NO es queixa de res d'això:
perill.foo.bar.baz();
perill();
const x: number = perill;
// ...però tot fallarà en execució 💥Evita any a tota costa
Usar any contagia el teu codi. Si una funció retorna any, aquesta falta de seguretat es propaga. Usa’l només quan estiguis migrant codi JS antic o sigui 100% impossible saber el tipus (i tot i així, prefereix unknown).
2. unknown: L’alternativa segura 🛡️
unknown és com any: accepta qualsevol valor. PERÒ (i és un gran però) no et deixa fer res amb ell fins que comprovis què és.
T’obliga a usar Narrowing (el que vam veure al Cap. #6) abans d’usar-lo.
let segur: unknown = "Hola món";
// Error: Object is of type 'unknown'.
// segur.toUpperCase();
// La forma correcta: Comprovar primer
if (typeof segur === "string") {
// Ara TS sap que és string
console.log(segur.toUpperCase());
}let segur: unknown = "Hola món";
// Error: Object is of type 'unknown'.
// segur.toUpperCase();
// La forma correcta: Comprovar primer
if (typeof segur === "string") {
// Ara TS sap que és string
console.log(segur.toUpperCase());
}Això és ideal per a respostes d’APIs externes o JSON.parse(), on realment no saps què vindrà, però vols gestionar-ho de forma segura.
3. never: L’impossible 🚫
never és el tipus per a valors que mai poden ocórrer. És el tipus de retorn d’una funció que llança un error sempre (i per tant mai retorna) o un bucle infinit.
function error(missatge: string): never {
throw new Error(missatge);
}
// Aquesta funció mai retorna "undefined" ni res,
// la seva execució mai acaba exitosament.function error(missatge: string): never {
throw new Error(missatge);
}
// Aquesta funció mai retorna "undefined" ni res,
// la seva execució mai acaba exitosament.Exhaustiveness Checking (El truc pro)
L’ús més potent de never és assegurar-te que has cobert tots els casos possibles en un switch o unió.
type Estat = "Carregant" | "Exit" | "Error";
function getMissatge(s: Estat) {
switch (s) {
case "Carregant": return "⏳";
case "Exit": return "✅";
case "Error": return "❌";
default:
// Si demà afegeixes "Inactiu" a Estat,
// TS marcarà error aquí perquè "s" no seria never.
const _exhaustiveCheck: never = s;
return _exhaustiveCheck;
}
}type Estat = "Carregant" | "Exit" | "Error";
function getMissatge(s: Estat) {
switch (s) {
case "Carregant": return "⏳";
case "Exit": return "✅";
case "Error": return "❌";
default:
// Si demà afegeixes "Inactiu" a Estat,
// TS marcarà error aquí perquè "s" no seria never.
const _exhaustiveCheck: never = s;
return _exhaustiveCheck;
}
}Si en el futur algú afegeix | "Inactiu" al tipus Estat i oblida actualitzar el switch, TypeScript llançarà un error en temps de compilació dient que Type 'string' is not assignable to type 'never'. Màgia! ✨
4. Exercici: Domant el Desconegut
Anem a posar en pràctica unknown. Tens una funció que rep una dada desconeguda. Per a usar-lo de forma segura, necessitaràs aplicar l’après en el capítol anterior (Type Guards).
La teva missió:
- Comprovar si és un
string. - Si ho és, retornar-lo en MAJÚSCULES.
- Si NO ho és, llançar un error dient exactament:
"No és text".
Amb això tanquem el bloc de tipus avançats de seguretat! Ara el teu codi serà molt més robust. 🛡️
Resum
any: “M’és igual tot, deixa’m en pau”. (Insegur, evita’l).unknown: “No em refio de tu, ensenya’m el teu DNI”. (Segur, obliga a verificar).never: “Això no hauria de passar”. (Usat per a codi inabastable).