TypeScript permite tipificar eventos propios para garantizar el funcionamiento correcto con sus objetos, especialmente en aplicaciones web o al trabajar con el patrón pub/sub. Para la tipificación de eventos, a menudo se utiliza el tipo CustomEvent con un tipo genérico parametrizado:
interface MyEventDetail { username: string; age: number; } const event = new CustomEvent<MyEventDetail>('user:create', { detail: { username: 'alice', age: 30 } }); document.addEventListener('user:create', (e: CustomEvent<MyEventDetail>) => { console.log(e.detail.username); });
Puntos clave:
CustomEvent<T>) sea el mismo tanto al crear el evento como al procesarlo.any o object.A menudo preguntan: "¿Se puede tipificar directamente el objeto event como
CustomEvent<Type>en el manejador si el evento es generado por una biblioteca externa?"
La respuesta correcta: Solo si se sabe con absoluta certeza que la biblioteca genera eventos a través de CustomEvent con genéricos. De lo contrario, la tipificación será incorrecta y pueden ocurrir errores en tiempo de ejecución.
Ejemplo:
document.addEventListener('some-event', (e: Event) => { // Incorrecto: 'e' no necesariamente es CustomEvent const detail = (e as CustomEvent<{ id: number }>).detail; // Esto causará un error si el evento no es CustomEvent });
Historia
En el proyecto se utilizó una abstracción pub/sub y se lanzaron eventos a través de un simple Event en lugar de CustomEvent. Se esperaban acceder a event.detail, pero el Event base no tiene este campo, lo que llevó a un undefined silencioso y errores difíciles de rastrear.
Historia
Parte del equipo tipificaba eventos personalizados a través de any para implementar "más rápido" los manejadores en diferentes escenarios. Como resultado, más tarde comenzaron a surgir errores debido a la transmisión de diferentes estructuras de datos a través de detail, y TypeScript no señalizó las discrepancias.
Historia
En un proyecto, se comenzó a utilizar la tipificación de eventos como CustomEvent<string>, al mismo tiempo que se pasaban objetos complejos a través de detail. Por error, se serializaba detail, lo que llevaba a la necesidad de hacer un JSON.parse adicional en el lado del manejador y a la pérdida de tipificación dentro de TypeScript.