TypeScript permet de typiser les événements personnalisés afin de garantir le bon fonctionnement avec leurs objets, en particulier dans les applications web ou lors de l'utilisation du modèle pub/sub. Pour la typisation des événements, on utilise souvent le type CustomEvent avec un type générique paramétré :
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); });
Points clés :
CustomEvent<T>) correspond à la fois lors de la création de l'événement et lors de son traitement.any ou object.On demande souvent : « Peut-on typiser l'objet event directement en tant que
CustomEvent<Type>dans le gestionnaire, si l'événement est généré par une bibliothèque tierce ? »
La réponse correcte : Seulement si l'on sait avec certitude que la bibliothèque génère des événements via CustomEvent avec un générique. Sinon, la typisation sera incorrecte, et des erreurs de runtime peuvent survenir.
Exemple :
document.addEventListener('some-event', (e: Event) => { // Erroné : 'e' n'est pas forcément un CustomEvent const detail = (e as CustomEvent<{ id: number }>).detail; // Cela entraînera une erreur si l'événement n'est pas un CustomEvent });
Histoire
Dans un projet, nous avons utilisé une abstraction pub/sub et lancé des événements via un simple Event au lieu de CustomEvent. Nous nous attendions à pouvoir accéder à event.detail, mais l'objet Event de base n'a pas ce champ, ce qui a conduit à un undefined silencieux et à des bugs difficiles à détecter.
Histoire
Une partie de l'équipe a typisé des événements personnalisés via any, pour "aller plus vite" dans l'implémentation des gestionnaires pour différents scénarios. En conséquence, des erreurs ont commencé à survenir plus tard à cause du passage de différentes structures de données via detail, alors que TypeScript ne signalait pas les incohérences.
Histoire
Dans un projet, nous avons commencé à utiliser la typisation des événements comme CustomEvent<string>, en passant des objets complexes via detail. Par erreur, nous avons sérialisé detail, ce qui a entraîné la nécessité d'effectuer un JSON.parse supplémentaire du côté du gestionnaire, et la perte de typisation à l'intérieur de TypeScript.