ProgramaciónDesarrollador Frontend

Describe el mecanismo de tipo de guardia (Type Guards) en TypeScript y da ejemplos de su uso. ¿Cuál es la principal ventaja y qué matices se deben tener en cuenta al implementar funciones de tipo guardia personalizadas?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

Los Type Guards son mecanismos que permiten afinar el tipo de una variable en un bloque de código, basándose en ciertas comprobaciones (por ejemplo, utilizando typeof, instanceof, o funciones especiales que devuelven expresiones del tipo param is SomeType).

La principal ventaja es la seguridad y la eliminación de errores de ejecución mediante la verificación de tipos en tiempo de compilación.

Ejemplo:

interface Fish { swim: () => void } interface Bird { fly: () => void } function isFish(pet: Fish | Bird): pet is Fish { return (pet as Fish).swim !== undefined; } function move(pet: Fish | Bird) { if (isFish(pet)) { pet.swim(); } else { pet.fly(); } }

Aquí, la función isFish es un guardia de tipo personalizado.

Matices:

  • Cualquier comprobación lógica adicional debe estar estrictamente relacionada con la tipificación.
  • Los errores en las funciones de guardia de tipo pueden llevar a una definición incorrecta de tipos en tiempo de ejecución.

Pregunta trampa.

Pregunta: "¿El compilador de TypeScript siempre se basará solamente en el valor de retorno de la función guardia, o utiliza algún otro análisis dentro de la función?"

Respuesta: El compilador de TypeScript se basa únicamente en la firma del valor de retorno param is Type. Lo que ocurre dentro de la función guardia no se analiza en términos de corrección de implementación.

Ejemplo (error peligroso!):

function isString(x: any): x is string { return true; } // El compilador considerará que siempre es una cadena, aunque no sea así: if (isString(123)) { // aquí x es de tipo string, pero en realidad es un número }

Ejemplos de errores reales debido al desconocimiento de las sutilezas del tema.


Historia

En un proyecto con DTOs compartidos entre el frontend y el backend, olvidaron agregar una verificación estricta dentro de la guardia de tipo personalizada. Como resultado, algunos datos se interpretaron incorrectamente como el tipo necesario, lo que provocó fallos en el cliente al intentar utilizar una propiedad faltante.


Historia

Un desarrollador escribió una guardia de tipo, confiando en un campo opcional, sin embargo, la estructura de datos permitía no tener este campo en absoluto. Como resultado, faltaba la rama en el switch-case de tipos, y el compilador no emitió advertencias; en tiempo de ejecución, surgieron excepciones.


Historia

En uno de los servicios, al migrar a TypeScript, se confiaron únicamente en los type guards incorporados (typeof, instanceof). Al cambiar el prototipo de los objetos durante la verificación, se volvieron incorrectos, lo que causó errores difíciles de depurar en producción.