{"id":21600028,"url":"https://github.com/derzade/typescript-event-target","last_synced_at":"2025-04-05T18:05:50.627Z","repository":{"id":62028741,"uuid":"473288066","full_name":"DerZade/typescript-event-target","owner":"DerZade","description":"Strictly typed EventTarget that directly extends EventTarget to function as a drop-in replacement. It works with all Event-Types and accounts for basically no additional bundle-size.","archived":false,"fork":false,"pushed_at":"2025-02-20T09:44:58.000Z","size":421,"stargazers_count":41,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-29T17:04:01.079Z","etag":null,"topics":["event-target","typed","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DerZade.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-23T17:19:08.000Z","updated_at":"2025-03-12T11:13:57.000Z","dependencies_parsed_at":"2024-11-20T09:10:42.929Z","dependency_job_id":"25bd62b3-fc83-49c5-86f1-153b91b827cc","html_url":"https://github.com/DerZade/typescript-event-target","commit_stats":{"total_commits":49,"total_committers":1,"mean_commits":49.0,"dds":0.0,"last_synced_commit":"7730f4570b87a05512880677a4abbb814b8c2da9"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DerZade%2Ftypescript-event-target","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DerZade%2Ftypescript-event-target/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DerZade%2Ftypescript-event-target/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DerZade%2Ftypescript-event-target/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DerZade","download_url":"https://codeload.github.com/DerZade/typescript-event-target/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247378138,"owners_count":20929296,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["event-target","typed","typescript"],"created_at":"2024-11-24T18:17:09.854Z","updated_at":"2025-04-05T18:05:50.586Z","avatar_url":"https://github.com/DerZade.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TypedEventTarget [![NPM](https://img.shields.io/npm/v/typescript-event-target?style=flat-square)](https://npmjs.com/package/typescript-event-target) [![JSR](https://img.shields.io/jsr/v/%40derzade/typescript-event-target?style=flat-square)](https://jsr.io/@derzade/typescript-event-target/) [![Deno](https://img.shields.io/badge/available%20on-deno.land/x-lightgrey.svg?logo=deno\u0026labelColor=black\u0026style=flat-square)](https://deno.land/x/typescript_event_target/) [![License](https://img.shields.io/github/license/derzade/typescript-event-target?style=flat-square)](/LICENSE)\n\n_Strictly typed [`EventTarget`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget) that directly extends `EventTarget` to function as a drop-in replacement. It works with all Event-Types and accounts for basically no additional bundle-size._\n\n## Motivation\n\nSince `EventTarget` support landed in NodeJS v14.5, they are the only way to go forward, when talking about event driven JS.  \nBut `EventTarget` lacks in terms of developer experience and Typescript integration. To be specific:\n\n- No strictly typed event listeners \u0026 events\n- Missing proper IntelliSense integration\n- No auto-complete for event types\n\nThe weird thing is, that with JS-native objects, which implement `EventTarget` (like WebSocket, Worker or any HTML-Elements), you get all those features out of the box:\n\n\u003cimg alt=\"Visual Studio Code\" src=\"https://user-images.githubusercontent.com/12705416/203958225-7ecf9b96-8004-44d0-b670-8fcb1ae62394.png\" style=\"width: 75%\"\u003e\n\n**This package aims to** fix these shortcomings and **add all these missing features for custom EventTargets**.\n\n## Installation\n\n### NPM\n\nInstall the package:\n\n```\nnpm i --save typescript-event-target\n```\n\nThen import as follows:\n\n```ts\nimport { TypedEventTarget } from 'typescript-event-target';\n```\n\n### Deno\n\nEither install from [JSR](https://jsr.io/@derzade/typescript-event-target/doc/~/TypedEventListenerObject):\n\n```\ndeno add @derzade/typescript-event-target\n```\n\nor import directly form `deno.land/x/`:\n\n```ts\nimport { TypedEventTarget } from 'https://deno.land/x/typescript_event_target/mod.ts';\n```\n\n\u003e :warning: Warning: It is best practice to \"pin\" to a particular version. `https://deno.land/x/` supports using git tags in the URL to direct you at a particular version. So to use version 1.0.0 of TypedEventTarget, you would want to import `https://deno.land/x/typescript_event_target@v1.0.0/mod.ts`.\n\n## Usage\n\n1. [Basic Example](#basic-example)\n1. [Dispatching Events](#dispatching-events)\n1. [Extending `TypedEventTarget`](#extending-typedeventtarget)\n1. [Different Event Types](#different-event-types)\n\n### Basic Example\n\n```ts\n// Step 1: Create an interface, which\n// includes all dispatchable events\ninterface MyEventMap {\n    hello: Event;\n    time: CustomEvent\u003cnumber\u003e;\n}\n\n// Step 2: Create your TypedEventTarget, with\n// the EventMap as the type parameter\nconst eventTarget = new TypedEventTarget\u003cMyEventMap\u003e();\n\n// Step 3: Strictly typed EventListeners 🎉\neventTarget.addEventListener('time', (event) =\u003e {\n    // event is of type CustomEvent\u003cnumber\u003e\n\n    const time = event.detail;\n\n    // time is of type number\n});\n```\n\n### Dispatching Events\n\n`TypedEventTarget` directly extends `EventTarget`, so [`dispatchEvent`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent) **works as expected**, but is marked as deprecated. The reason for this is that `dispatchEvent` cannot be strictly typed easily. Instead, `TypedEventTarget` introduces a `dispatchTypedEvent` method, which is strictly typed by taking an additional `_type` parameter (just used for type checking).\n\n```ts\ninterface MyEventMap {\n    time: CustomEvent\u003cnumber\u003e;\n}\n\nconst eventTarget = new TypedEventTarget\u003cMyEventMap\u003e();\n\neventTarget.dispatchTypedEvent(\n    'time',\n    new CustomEvent('time', { detail: Date.now() })\n);\n```\n\n### Extending `TypedEventTarget`\n\nInstead of directly instantiating `TypedEventTarget`, you can also extend it:\n\n```ts\ninterface MyEventMap {\n    time: CustomEvent\u003cnumber\u003e;\n    // [...]\n}\n\nclass MyEventTarget extends TypedEventTarget\u003cMyEventMap\u003e {\n    /* [...] */\n}\n\nconst myTarget = new MyEventTarget();\nmyTarget.addEventListener('time', (e) =\u003e {\n    /* [...] */\n});\n```\n\n### Different Event Types\n\nYour EventMap can include [`Event`](https://developer.mozilla.org/en-US/docs/Web/API/Event) as well as any type, that extends [`Event`](https://developer.mozilla.org/en-US/docs/Web/API/Event). These can be native Events or even own classes:\n\n```ts\nclass MyEvent extends Event {\n    /* [...] */\n}\n\nclass MyEventMap {\n    boring: Event;\n    custom: CustomEvent\u003cnumber\u003e;\n    mine: MyEvent;\n    mouse: MouseEvent;\n    keyboard: KeyboardEvent;\n}\n\nconst eventTarget = new TypedEventTarget\u003cMyEventMap\u003e();\n\neventTarget.addEventListener('mine', (e) =\u003e {\n    // e is of type MyEvent\n});\n```\n\n## Bundle Size\n\nThis package mostly only contains TypeScript definitions. Therefore, it amounts up to basically no bundle size. The only thing that is bundled is the `dispatchTypedEvent`-method, which is just a simple wrapper around the native `dispatchEvent`-method.\n\n|           |      Deflate |        Brotli |      Gzip | Uncompressed |\n| --------- | -----------: | ------------: | --------: | -----------: |\n| ES Module | **92 Bytes** |      95 Bytes | 110 Bytes |    119 Bytes |\n| Common JS |    336 Bytes | **308 Bytes** | 354 Bytes |    599 Bytes |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fderzade%2Ftypescript-event-target","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fderzade%2Ftypescript-event-target","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fderzade%2Ftypescript-event-target/lists"}