Saltar al contenido principal
eLearner.app
Módulo 5 · Lección 1 de 29/14 en el curso~15 min
Lecciones del módulo (1/2)

Guardias de Tipo

El estrechamiento de tipos (Type Narrowing) es uno de los conceptos más importantes en TypeScript. A menudo, sin embargo, las guardas de tipo estándar como typeof o instanceof no son suficientes para objetos personalizados complejos. Aquí es donde entran en juego las Guardas de Tipo Personalizadas (Custom Type Guards).


Guardas de Tipo Estándar

Comencemos resumiendo cómo TypeScript restringe los tipos usando los operadores estándar de JavaScript:

TS
function processInput(val: string | number) {
  if (typeof val === 'string') {
    // Qui 'val' è di tipo string
    console.log(val.toUpperCase());
  } else {
    // Qui 'val' è di tipo number
    console.log(val.toFixed(2));
  }
}

Guardas de Tipo Personalizadas (operador is)

Para definir una guarda de tipo personalizada, creamos una función que devuelve un predicado de tipo en el formato parameterName is Type en lugar del tipo de retorno booleano estándar.

La función debe devolver un booleano (true o false). Si devuelve true, TypeScript sabrá que el parámetro pasado es del tipo especificado.

TS
interface Cat {
  name: string;
  meow(): void;
}

interface Dog {
  name: string;
  bark(): void;
}

// Questa è una guardia di tipo personalizzata
function isCat(animal: Cat | Dog): animal is Cat {
  return (animal as Cat).meow !== undefined;
}

function makeNoise(pet: Cat | Dog) {
  if (isCat(pet)) {
    // Qui TypeScript sa che 'pet' è un Cat
    pet.meow();
  } else {
    // Qui TypeScript sa che 'pet' è un Dog
    pet.bark();
  }
}

Seguridad y Conversión (as vs Type Guards)

El type casting (ej. val as Cat) obliga al compilador a confiar en el desarrollador, sin ninguna verificación real en tiempo de ejecución. Si el objeto en tiempo de ejecución no cumple con las expectativas, el código fallará silenciosamente o lanzará excepciones.

Las guardas de tipo personalizadas permiten, en cambio, realizar una verificación robusta y dinámica en tiempo de ejecución, informando de forma segura y precisa al compilador de TypeScript sobre el tipo real de la variable:

TS
function processInput(input: unknown) {
  // casting insicuro: potrebbe rompersi se input non ha il metodo split
  // const str = input as string;
  // console.log(str.split(' '));

  // guardia sicura
  if (isString(input)) {
    console.log(input.split(' ')); // Sicuro al 100%!
  }
}

Pruébalo tú

Ejercicio 1: Guarda de Tipo para Cadenas

Ejercicio#ts.m5.l1.e1
Intentos: 0Cargando...

Crea una función simple llamada isString que funcione como guarda de tipo personalizada para verificar si un valor unknown es una cadena.

Cargando editor...
Mostrar pista

El tipo de retorno de la función debe ser val is string, y debes usar typeof para verificar si es igual a 'string'.

Solución disponible después de 3 intentos

Ejercicio 2: Guarda de Tipo para Usuario Premium

Ejercicio#ts.m5.l1.e2
Intentos: 0Cargando...

Dados los tipos User y PremiumUser, escribe una función de guarda de tipo isPremiumUser(user: User): user is PremiumUser que verifique si el usuario tiene el rol 'premium'.

Cargando editor...
Mostrar pista

Define la firma como function isPremiumUser(user: User): user is PremiumUser y compara user.role con 'premium'.

Solución disponible después de 3 intentos

Ejercicio 3: Verificación de Objeto de Error Personalizado

Ejercicio#ts.m5.l1.e3
Intentos: 0Cargando...

Implementa la función isCustomError(err: unknown): err is CustomError que verifique si un valor desconocido es un objeto CustomError no nulo que posee la clave 'code'.

Cargando editor...
Mostrar pista

Verifica primero que typeof err sea 'object' y no sea null, luego usa el operador 'in' para verificar la presencia de la propiedad 'code'.

Solución disponible después de 3 intentos

Ejercicio 4: Guarda de Tipo Admin

Ejercicio#ts.m5.l1.e4
Intentos: 0Cargando...

Dadas dos interfaces User (con propiedad role: string) y Admin (que extiende User y tiene una propiedad adminToken: string), escribe una función type guard llamada isAdmin que acepte un objeto user de tipo User y devuelva un predicado de tipo user is Admin. La guarda debe verificar que el role del usuario sea igual a 'admin'.

Cargando editor...
Mostrar pista

Define la firma como function isAdmin(user: User): user is Admin y controla que user.role === 'admin'.

Solución disponible después de 3 intentos