TypeScript 的类型系统和 JavaScript 的事件系统似乎有点相性不合,具体点讲,如果你想在里面加一些自定义的类型标注就必须的直接改 EventTarget (或者 EventEmitter)的类型定义,再或者用类似 event.detail as SomeType
的方式构建一种很微妙的「类型安全」氛围。
这两种方法都是我不喜欢的,前者会对类型系统造成污染,个人更加喜欢把「做同一件事情的代码放在一起」,但是按照前者的思路,类型定义和真正的 Event Listener 会「身首异处」,看起来非常可怜,而且,比如你在模块 A 中没有用到模块 B 声明的类型定义,但是它的 EventTarget 还是会带着模块 B 的类型定义,看起来就很脏,有一种全局变量满天飞的味道。而第二种做法则完全没有没有做到真正的类型安全,如果你 as 错了,那一切都没得聊了。
前些日子花了点心思研究了一下这种东西究竟要怎么写,最后选择了一种把我自己恶心到了的方法,可以做到大面上干净清爽但是内部恶臭得要死。