https://github.com/derzade/typescript-event-target
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.
https://github.com/derzade/typescript-event-target
event-target typed typescript
Last synced: over 1 year ago
JSON representation
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.
- Host: GitHub
- URL: https://github.com/derzade/typescript-event-target
- Owner: DerZade
- License: mit
- Created: 2022-03-23T17:19:08.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2025-02-20T09:44:58.000Z (over 1 year ago)
- Last Synced: 2025-03-29T17:04:01.079Z (over 1 year ago)
- Topics: event-target, typed, typescript
- Language: TypeScript
- Homepage:
- Size: 411 KB
- Stars: 41
- Watchers: 1
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# TypedEventTarget [](https://npmjs.com/package/typescript-event-target) [](https://jsr.io/@derzade/typescript-event-target/) [](https://deno.land/x/typescript_event_target/) [](/LICENSE)
_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._
## Motivation
Since `EventTarget` support landed in NodeJS v14.5, they are the only way to go forward, when talking about event driven JS.
But `EventTarget` lacks in terms of developer experience and Typescript integration. To be specific:
- No strictly typed event listeners & events
- Missing proper IntelliSense integration
- No auto-complete for event types
The 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:

**This package aims to** fix these shortcomings and **add all these missing features for custom EventTargets**.
## Installation
### NPM
Install the package:
```
npm i --save typescript-event-target
```
Then import as follows:
```ts
import { TypedEventTarget } from 'typescript-event-target';
```
### Deno
Either install from [JSR](https://jsr.io/@derzade/typescript-event-target/doc/~/TypedEventListenerObject):
```
deno add @derzade/typescript-event-target
```
or import directly form `deno.land/x/`:
```ts
import { TypedEventTarget } from 'https://deno.land/x/typescript_event_target/mod.ts';
```
> :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`.
## Usage
1. [Basic Example](#basic-example)
1. [Dispatching Events](#dispatching-events)
1. [Extending `TypedEventTarget`](#extending-typedeventtarget)
1. [Different Event Types](#different-event-types)
### Basic Example
```ts
// Step 1: Create an interface, which
// includes all dispatchable events
interface MyEventMap {
hello: Event;
time: CustomEvent;
}
// Step 2: Create your TypedEventTarget, with
// the EventMap as the type parameter
const eventTarget = new TypedEventTarget();
// Step 3: Strictly typed EventListeners 🎉
eventTarget.addEventListener('time', (event) => {
// event is of type CustomEvent
const time = event.detail;
// time is of type number
});
```
### Dispatching Events
`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).
```ts
interface MyEventMap {
time: CustomEvent;
}
const eventTarget = new TypedEventTarget();
eventTarget.dispatchTypedEvent(
'time',
new CustomEvent('time', { detail: Date.now() })
);
```
### Extending `TypedEventTarget`
Instead of directly instantiating `TypedEventTarget`, you can also extend it:
```ts
interface MyEventMap {
time: CustomEvent;
// [...]
}
class MyEventTarget extends TypedEventTarget {
/* [...] */
}
const myTarget = new MyEventTarget();
myTarget.addEventListener('time', (e) => {
/* [...] */
});
```
### Different Event Types
Your 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:
```ts
class MyEvent extends Event {
/* [...] */
}
class MyEventMap {
boring: Event;
custom: CustomEvent;
mine: MyEvent;
mouse: MouseEvent;
keyboard: KeyboardEvent;
}
const eventTarget = new TypedEventTarget();
eventTarget.addEventListener('mine', (e) => {
// e is of type MyEvent
});
```
## Bundle Size
This 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.
| | Deflate | Brotli | Gzip | Uncompressed |
| --------- | -----------: | ------------: | --------: | -----------: |
| ES Module | **92 Bytes** | 95 Bytes | 110 Bytes | 119 Bytes |
| Common JS | 336 Bytes | **308 Bytes** | 354 Bytes | 599 Bytes |