TypeScript实现类型安全的EventEmitter

yizhihongxing

下面是 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中常规的文件操作总结

    下面我将为你详细讲解“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
  • Node.js图片处理库sharp的使用

    下面是关于Node.js图片处理库sharp使用的完整攻略。 简介 Sharp是一个由libvips图像处理库提供支持的快速、高效、功能丰富的Node.js图片处理库。它可以对图片进行缩放、裁剪、旋转等常见的操作,并且可以进行更进一步的高级处理,例如渐进式图片输出、代码优化等功能。 安装 首先需要通过npm安装sharp: npm install sharp…

    node js 2023年6月8日
    00
  • nodejs实用示例 缩址还原

    请看以下攻略: nodejs实用示例:缩址还原 在网站或者移动应用开发中,我们经常需要将长网址转化为短网址,以提高用户体验。本文将介绍如何使用 Node.js 实现一个简单的缩址功能。 要点 缩址算法:将长网址通过散列算法转化为短网址。 数据库保存:使用 MongoDB 数据库保存长网址和短网址的映射关系。 路由设置:将短链接重定向到长链接,需要根据短链接从…

    node js 2023年6月8日
    00
  • JS模板编译的实现详情

    JS模板编译是前端开发中非常重要的一部分,它可以实现页面数据和UI的分离以及提高渲染速度。本文将从以下几个方面详细讲解JS模板编译的实现详情。 什么是JS模板编译? JS模板编译是一种将HTML模板中的数据和逻辑转换为可执行的JavaScript函数的过程。在运行时,编译后的模板可以通过传入数据,并在浏览器中运行,生成最终的HTML内容。 实现JS模板编译的…

    node js 2023年6月8日
    00
  • Angular Renderer (渲染器)的具体使用

    Angular Renderer 是 Angular 的一个基础设施,它是与 DOM 交互的方便的方式。使用 Renderer 可以将组件与底层的 DOM 的具体实现(例如 Angular 所使用的正常 DOM 和 Web Worker 的缺失 DOM)解耦。渲染器可以帮助你在渲染的时候实现跨平台兼容性,例如有一些渲染器支持在 Angular 中使用 Nat…

    node js 2023年6月8日
    00
  • 从零揭秘npm install的黑科技

    当我们执行 npm install 命令时,实际上发生了很多事情,这些事情涉及到Node.js的包管理、网络传输、依赖分析与解析等方面。本文将从这些方面介绍针对 npm install 核心机制的一些优化技巧,以帮助大家更好地理解这个过程,以及如何在实际开发中提高 npm install 的效率。 NPM的包管理 NPM执行 npm install 命令时,…

    node js 2023年6月8日
    00
  • node.js连接mongoose数据库方法详解

    针对您的问题,我将详细讲解“node.js连接mongoose数据库方法详解”的完整攻略。 标题 1.什么是mongoose Mongoose是一个Node.js的MongoDB对象模型工具,可以在异步环境下工作。同时也是Node.js和MongoDB数据交互的重要中间件之一,可以实现对象模型分析,为模型的属性添加验证规则等等。使用mongoose可以让我们…

    node js 2023年6月8日
    00
  • node.js中的emitter.emit方法使用说明

    我们来详细讲解一下”node.js中的emitter.emit方法使用说明”的完整攻略。 什么是EventEmitter EventEmitter是Node.js的一个重要模块,用来实现事件的订阅和发布。它是实现事件驱动编程的基础,同时它也是Node.js中许多API的基础。 EventEmitter是一个构造函数,在使用它之前需要通过require(‘ev…

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