TypeScript实现类型安全的EventEmitter

下面是 TypeScript 实现类型安全的 EventEmitter 的完整攻略。

什么是 TypeScript EventEmitter?

EventEmitter 是 Node.js 中常用的一个模块,用于实现事件机制。可以通过绑定事件来监听对象或函数的状态变化,从而实现异步回调。

TypeScript 在 EventEmitter 的基础上实现了类型安全,能够避免一些类型错误,让代码更加健壮。

实现方式

通过 TypeScript 的泛型特性,我们可以在定义 EventEmitter 类时规定事件名和事件数据的类型,从而实现类型安全。下面是一个示例:

interface Events {
  [eventName: string]: any
}

type Listener<T> = (arg: T) => void

class TypedEventEmitter<Events> {
  private map = new Map<keyof Events, Listener<Events[keyof Events]>[]>()

  on<K extends keyof Events>(eventName: K, listener: Listener<Events[K]>) {
    const listeners = this.map.get(eventName) || []
    listeners.push(listener as Listener<Events[K]>)
    this.map.set(eventName, listeners)
  }

  emit<K extends keyof Events>(eventName: K, arg: Events[K]) {
    const listeners = this.map.get(eventName) || []
    listeners.forEach(listener => listener(arg))
  }
}

这里我们定义了一个泛型类 TypedEventEmitter,Events 类型定义了事件名和事件数据类型的键值对。Listener 是事件回调函数的类型,它接收一个参数为泛型类型 T,返回值为空。

在 TypedEventEmitter 类中,我们使用了 Map 来保存事件名与事件回调函数的数组之间的映射关系。在 on 方法中,我们向数组中添加回调函数,并根据事件名将它们存放到 map 中。在 emit 方法中,我们根据事件名获取所有回调函数并依次执行。

示例

下面是一个使用 TypedEventEmitter 实现服务端 WebSocket 的示例:

interface WSEvents {
  close: void
  message: string
}

class WebSocketServer {
  private emitter = new TypedEventEmitter<WSEvents>()
  private server: WebSocket.Server

  constructor(port: number) {
    this.server = new WebSocket.Server({ port })
    this.server.on('connection', socket => {
      socket.on('close', () => this.emitter.emit('close', undefined))
      socket.on('message', data => this.emitter.emit('message', data))
    })
  }

  on<K extends keyof WSEvents>(eventName: K, listener: Listener<WSEvents[K]>) {
    this.emitter.on(eventName, listener)
  }
}

这里我们定义了一个 WebSocketServer 类来封装 socket 实例。使用 TypedEventEmitter 来发送和处理消息。在 on 方法中,我们可以很方便地指定需要监听的事件名和对应的回调,避免了类型错误的风险,代码更加清晰易懂。

总结

在 TypeScript 中实现类型安全的 EventEmitter,除了增强了代码可维护性和可读性之外,还让我们不必担心类型推断错误,提升了代码的可靠性。现在,你已经学会了如何使用 TypeScript 的泛型和类来实现 EventEmitter,可以在你的开发中尝试使用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:TypeScript实现类型安全的EventEmitter - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • vue导入新工程 “node_modules依赖”问题

    在Vue.js中,想要使用第三方插件或库,一般会使用npm安装插件或库,并将其导入到新的工程中。但是,在导入的过程中,可能会遇到“node_modules依赖”问题,即在项目中找不到安装的插件或库。下面是详细的攻略过程及示例说明: 1. 确认项目中是否安装了所需的依赖 在导入插件或库之前,需要先确定当前项目中是否已经安装了所需的依赖。可以打开终端,并进入项目…

    node js 2023年6月8日
    00
  • vue: WebStorm设置快速编译运行的方法

    当你在使用Vue开发应用程序时,你会发现频繁编译和运行是开发的常态。为了提高开发效率,很多开发者都会在IDE中设置快捷键做到快速编译和运行。在WebStorm中,也可以通过设置快捷键实现快速编译和运行Vue应用程序。下面是具体步骤: 第一步:设置环境变量 在打开WebStorm之前,需要先设置好NODE_ENV环境变量。为此,可以在命令行中输入以下命令: e…

    node js 2023年6月8日
    00
  • 解决vue cli4升级sass-loader(v8)后报错问题

    针对“解决vue cli4升级sass-loader(v8)后报错问题”,我会提供以下完整攻略: 问题背景 在升级 sass-loader 到 v8 版本之后,如果项目依赖了 node-sass,就会在启动 npm run serve 命令时遇到下面的错误: Module build failed (from ./node_modules/sass-load…

    node js 2023年6月8日
    00
  • Nodejs进阶:express+session实现简易登录身份认证

    下面我将为你详细讲解“Nodejs进阶:express+session实现简易登录身份认证”的完整攻略。本攻略主要分为以下几个部分: 什么是session express-session的使用 实现简易登录身份认证的步骤 示例说明 什么是session 在Web开发中,我们常常需要通过用户的身份认证来实现一些特殊的操作。而在HTTP的无状态协议中,为了保存用…

    node js 2023年6月8日
    00
  • nodejs遍历文件夹下并操作HTML/CSS/JS/PNG/JPG的方法

    针对这个问题,我可以提供以下的解决方案: 1. 使用Node.js的文件系统(fs)模块遍历文件夹 首先我们需要使用Node.js的fs模块来操作文件系统,并通过它来遍历目录下的文件及子目录,示例代码如下: const fs = require(‘fs’); const path = require(‘path’); const traverseDir = …

    node js 2023年6月8日
    00
  • 整理几个关键节点深入理解nodejs

    整理几个关键节点深入理解 Node.js 的完整攻略如下: 1. 了解 Node.js 的事件循环机制 Node.js 是基于事件驱动的异步编程模型,它使用事件循环机制来处理 I/O 操作。事件循环机制包括以下步骤: 检查当前是否有待处理的事件; 如果有,执行事件处理函数; 如果没有,则挂起程序等待事件到来。 理解事件循环机制对于编写高效的 Node.js …

    node js 2023年6月8日
    00
  • 详解React Angular Vue三大前端技术

    详解React Angular Vue三大前端技术 React、Angular和Vue是目前前端技术中最受欢迎的三种框架。在这篇攻略中,我们将会详细讲解这三种框架的特点、优缺点以及如何选择适合自己的框架。 React React是由Facebook开发并维护的一个JavaScript库,用于构建大型、高性能的用户界面。它有以下特点: 采用Virtual DO…

    node js 2023年6月8日
    00
  • Node.js中常规的文件操作总结

    下面我将为你详细讲解“Node.js中常规的文件操作总结”的完整攻略。 1. 文件操作方法 Node.js中提供了一系列的文件操作方法,常用的有以下几种: 1.1 fs.access(path[, mode], callback) 用于检查文件或目录是否可访问。 const fs = require(‘fs’); fs.access(‘/path/to/fi…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部