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日

相关文章

  • 详解Node.js包的工程目录与NPM包管理器的使用

    非常感谢您对Node.js包的工程目录和NPM包管理器的关注。下面我将为您详细介绍相关知识。 1. Node.js包的工程目录 Node.js包的工程目录包含以下文件和目录: . ├── bin/ │ └── your-cli.js ├── lib/ │ ├── your-library.js │ ├── submodule1.js │ ├── submod…

    node js 2023年6月8日
    00
  • Nodejs 发送Post请求功能(发短信验证码例子)

    这是一个使用Node.js发送POST请求的攻略,使用一个发短信验证码的例子来说明。要实现这个功能,我们需要使用Node.js的http模块和querystring模块。 发送Post请求的步骤 引入 http 和 querystring 模块: javascript const http = require(‘http’); const querystri…

    node js 2023年6月8日
    00
  • Node 切片拼接及地图导出实例详解

    Node 切片拼接及地图导出实例详解 本文将介绍如何使用 Node.js 实现切片拼接和地图导出功能。 准备工作 在开始操作之前,需要先安装以下两个模块: gm:该模块用于处理图像,可以用来进行图像拼接。 mapnik:该模块为 Node.js 提供了一个与 Mapnik 库交互的接口,可以用来生成地图。 可以使用以下命令行进行安装: npm install…

    node js 2023年6月8日
    00
  • node模块机制与异步处理详解

    Node模块机制与异步处理详解 1. Node模块机制 Node的模块机制是通过CommonJS规范实现的,它允许我们将代码封装成可重用的模块,并在不同的文件中进行引用。Node中有三种类型的模块: 核心模块:Node内置的模块,例如fs和http。 文件模块:位于本地文件系统中的模块,通过相对或绝对路径引用。 第三方模块:由NPM管理的模块,可以通过req…

    node js 2023年6月8日
    00
  • 浅析Node.js的Stream模块中的Readable对象

    浅析Node.js的Stream模块中的Readable对象 前言 在Node.js中,Stream是一个基础模块之一,负责处理数据流。它主要分为可写流(Writable)、可读流(Readable)以及双工流(Duplex)和转换流(Transform)四种类型。其中,我们今天将会重点探讨可读流(Readable)的属性和方法,以及如何使用它从流中读取数据…

    node js 2023年6月8日
    00
  • Node升级后vue项目node-sass报错问题及解决

    针对该问题,下面给出详细的解决攻略: 问题描述 在升级 Node 版本后,运行 Vue 项目时,可能会出现以下报错: Error: Node Sass could not find a binding for your current environment: Windows 64-bit with Node.js 12.x Found bindings f…

    node js 2023年6月8日
    00
  • Node.js 使用 zlib 内置模块进行 gzip 压缩

    当我们需要在 Node.js 服务器端进行文件传输或者数据传输时,有时候需要对数据进行压缩。Node.js 提供了内置的 zlib 模块来实现对数据的压缩和解压。本文将详细讲解如何使用 zlib 模块进行 gzip 压缩,并提供两个实例说明。 使用 zlib 模块进行 gzip 压缩 步骤一:引入 zlib 模块 在 Node.js 中我们使用 requir…

    node js 2023年6月8日
    00
  • node.js中Socket.IO的进阶使用技巧

    下面是“node.js中Socket.IO的进阶使用技巧”的完整攻略,包含两条示例说明。 Socket.IO概述 Socket.IO是一个实时应用程序框架,它使得在Web浏览器和服务器之间进行实时双向通信变得非常容易。它允许在混合Websockets、HTTP请求和轮询之间动态选择最佳的通信通道。在Node.js中,Socket.IO利用了底层的EventE…

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