编程前端开发工程师

如何在TypeScript中实现用户事件(custom events)的类型化?在处理事件对象和传递数据时应注意哪些细节?

用 Hintsage AI 助手通过面试

回答。

TypeScript允许对自定义事件进行类型化,以确保在处理其对象时的正确性,特别是在Web应用程序中或使用pub/sub模式时。对于事件类型化,通常使用带有参数化泛型类型的CustomEvent

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); });

关键细节:

  • 需要确保使用的事件类型(CustomEvent<T>)在创建事件和处理它时一致。
  • 如果使用原生事件,请使用基本事件类型,而不是anyobject
  • 创建自定义类型时,请记得事件的继承。

反向问题。

常常有人问:“如果事件是由第三方库创建的,能否在处理程序中直接将事件对象类型化为CustomEvent<Type>?”

正确的回答是:只有在绝对确定该库通过带有泛型的CustomEvent生成事件的情况下,才可以。否则,类型化将是不正确的,可能会导致运行时错误。

示例:

document.addEventListener('some-event', (e: Event) => { // 错误:'e' 不一定是 CustomEvent const detail = (e as CustomEvent<{ id: number }>).detail; // 如果事件不是 CustomEvent,这将导致错误 });

由于不了解主题细节而导致的实际错误示例。


故事

在项目中使用了pub/sub抽象,并通过简单的Event抛出事件,而不是使用CustomEvent。期望可以访问event.detail,但基本的Event没有这个字段,导致了沉默的undefined和难以捕捉的bug。


故事

团队的一部分通过any对自定义事件进行了类型化,以便"更快"地实现对不同场景的处理程序。结果,后来由于通过detail传递不同的数据结构而产生了错误,而TypeScript没有发出不一致的警告。


故事

在一个项目中,开始将事件类型化为CustomEvent<string>,同时通过detail传递复杂对象。错误地序列化了detail,导致在处理程序端需要额外执行JSON.parse并失去TypeScript内部的类型化。