From d06e4e74a4ce3ec88fe68345509b195e63cb51a9 Mon Sep 17 00:00:00 2001 From: Richie Bendall Date: Thu, 22 Sep 2022 21:00:24 +1200 Subject: [PATCH] Initial Commit Signed-off-by: Richie Bendall --- .editorconfig | 12 +++++++++ .gitattributes | 3 +-- .github/workflows/main.yml | 22 +++++++++++++++ .gitignore | 3 +++ .npmrc | 1 + index.d.ts | 46 +++++++++++++++++++++++++++++++ index.test-d.ts | 21 +++++++++++++++ license | 21 +++++++++++++++ package.json | 35 ++++++++++++++++++++++++ readme.md | 55 ++++++++++++++++++++++++++++++++++++++ tsconfig.json | 3 +++ 11 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 .editorconfig create mode 100644 .github/workflows/main.yml create mode 100644 .gitignore create mode 100644 .npmrc create mode 100644 index.d.ts create mode 100644 index.test-d.ts create mode 100644 license create mode 100644 package.json create mode 100644 readme.md create mode 100644 tsconfig.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..0e6ef88 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = tab + +[*.yml] +indent_style = space +indent_size = 2 diff --git a/.gitattributes b/.gitattributes index dfe0770..6313b56 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1 @@ -# Auto detect text files and perform LF normalization -* text=auto +* text=auto eol=lf diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..d50ada6 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,22 @@ +name: CI +on: + - push + - pull_request +jobs: + test: + name: Node.js ${{ matrix.node-version }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + node-version: + - 18 + - 16 + - 14 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..960be9a --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules +package-lock.json +yarn.lock \ No newline at end of file diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..9cf9495 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock=false \ No newline at end of file diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..1be575b --- /dev/null +++ b/index.d.ts @@ -0,0 +1,46 @@ +import type {ValueOf} from 'type-fest'; + +type EventListenerOrEventListenerObject = (value: Value) => void | { + handleEvent(value: Value): void; +}; + +/** +Strictly typed definitions for [`EventTarget`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget) + +Only used for type-checking; compiles to no code. + +@example +``` +import type StrictEventTarget from 'strict-event-target'; + +const target = new (EventTarget as typeof StrictEventTarget<{ + foo: string; // Event with data +}, [ + 'bar', // Event without data +]>); + +target.dispatchEvent(new CustomEvent('foo', {detail: 'The'})); + +target.dispatchEvent(new Event('bar')); +``` + +@example +``` +import type StrictEventTarget from 'strict-event-target'; + +class Foo extends (EventTarget as typeof StrictEventTarget<{ + foo: string; // Event with data +}, [ + 'bar', // Event without data +]>) {} +``` +*/ +export default class StrictEventTarget = {}, EventsWithoutData extends string[] = []> implements EventTarget { // eslint-disable-line @typescript-eslint/ban-types + addEventListener(name: Name, callback: EventListenerOrEventListenerObject> | null, options?: AddEventListenerOptions | boolean): void; // eslint-disable-line @typescript-eslint/ban-types + addEventListener>(name: Name, callback: EventListenerOrEventListenerObject | null, options?: AddEventListenerOptions | boolean): void; // eslint-disable-line @typescript-eslint/ban-types + + dispatchEvent(event: Event | CustomEvent>): boolean; + + removeEventListener(name: Name, callback: EventListenerOrEventListenerObject> | null, options?: EventListenerOptions | boolean): void; // eslint-disable-line @typescript-eslint/ban-types + removeEventListener>(name: Name, callback: EventListenerOrEventListenerObject | null, options?: EventListenerOptions | boolean): void; // eslint-disable-line @typescript-eslint/ban-types +} diff --git a/index.test-d.ts b/index.test-d.ts new file mode 100644 index 0000000..333c47a --- /dev/null +++ b/index.test-d.ts @@ -0,0 +1,21 @@ +import type StrictEventTarget from './index.js'; + +type EventsWithData = { + a: string; +}; + +type EventsWithoutData = ['b']; + +const target: StrictEventTarget = new (EventTarget as typeof StrictEventTarget)(); + +function aCallback(_event: CustomEvent) {} // eslint-disable-line @typescript-eslint/no-empty-function +function bCallback(_event: Event) {} // eslint-disable-line @typescript-eslint/no-empty-function + +target.addEventListener('a', aCallback); +target.addEventListener('b', bCallback); + +target.dispatchEvent(new CustomEvent('a', {detail: 'foo'})); +target.dispatchEvent(new Event('b')); + +target.removeEventListener('a', aCallback); +target.removeEventListener('b', bCallback); diff --git a/license b/license new file mode 100644 index 0000000..7cb9f9f --- /dev/null +++ b/license @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Richie Bendall + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/package.json b/package.json new file mode 100644 index 0000000..daf1fcc --- /dev/null +++ b/package.json @@ -0,0 +1,35 @@ +{ + "name": "strict-event-target", + "version": "0.0.0", + "description": "Strictly typed definitions for EventTarget", + "license": "MIT", + "repository": "Richienb/strict-event-target", + "author": { + "name": "Richie Bendall", + "email": "richiebendall@gmail.com" + }, + "type": "module", + "types": "index.d.ts", + "engines": { + "node": ">=14" + }, + "scripts": { + "test": "xo && tsd" + }, + "files": [ + "index.d.ts" + ], + "keywords": [ + "EventTarget", + "TypeScript" + ], + "dependencies": { + "type-fest": "^3.0.0" + }, + "devDependencies": { + "@sindresorhus/tsconfig": "^3.0.1", + "tsd": "^0.24.1", + "typescript": "^4.8.3", + "xo": "^0.52.3" + } +} \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..7098e6e --- /dev/null +++ b/readme.md @@ -0,0 +1,55 @@ +# strict-event-target + +> Strictly typed definitions for [`EventTarget`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget) + +Only used for type-checking; compiles to no code. + +## Install + +```sh +npm install strict-event-target +``` + +## Usage + +```ts +import type StrictEventTarget from 'strict-event-target'; + +const target = new (EventTarget as typeof StrictEventTarget<{ + foo: string; // Event with data +}, [ + 'bar', // Event without data +]>); + +target.dispatchEvent(new CustomEvent('foo', {detail: 'The'})); + +target.dispatchEvent(new Event('bar')); +``` + +```ts +import type StrictEventTarget from 'strict-event-target'; + +class Foo extends (EventTarget as typeof StrictEventTarget<{ + foo: string; // Event with data +}, [ + 'bar', // Event without data +]>) {} +``` + +## API + +### StrictEventTarget + +#### EventsWithData + +Type: `Record`\ +Default: `{}` + +Events that will be created with [`CustomEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent), thus being able to contain custom data. + +#### EventsWithoutData + +Type: `string[]`\ +Default: `[]` + +Events that will be created with [`Event`](https://developer.mozilla.org/en-US/docs/Web/API/Event). diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..e492827 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "@sindresorhus/tsconfig" +}