fix: better types for `on` (#12053)

- give autocompletion for types and more precise event types for html elements
- allow to pass other kinds of event target nodes, like window

closes #12027
fixes #12045
pull/12056/head
Simon H 6 months ago committed by GitHub
parent 59486beb29
commit f1d8ed64fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: better types for `on`

@ -33,7 +33,7 @@ export function replay_events(dom) {
/**
* @param {string} event_name
* @param {Element} dom
* @param {EventTarget} dom
* @param {EventListener} handler
* @param {AddEventListenerOptions} options
*/
@ -71,7 +71,31 @@ export function create_event(event_name, dom, handler, options) {
* rather than `addEventListener` will preserve the correct order relative to handlers added declaratively
* (with attributes like `onclick`), which use event delegation for performance reasons
*
* @template {HTMLElement} Element
* @template {keyof HTMLElementEventMap} Type
* @overload
* @param {Element} element
* @param {Type} type
* @param {(this: Element, event: HTMLElementEventMap[Type]) => any} handler
* @param {AddEventListenerOptions} [options]
* @returns {() => void}
*/
/**
* Attaches an event handler to an element and returns a function that removes the handler. Using this
* rather than `addEventListener` will preserve the correct order relative to handlers added declaratively
* (with attributes like `onclick`), which use event delegation for performance reasons
*
* @overload
* @param {EventTarget} element
* @param {string} type
* @param {EventListener} handler
* @param {AddEventListenerOptions} [options]
* @returns {() => void}
*/
/**
* @param {EventTarget} element
* @param {string} type
* @param {EventListener} handler
* @param {AddEventListenerOptions} [options]
@ -119,12 +143,12 @@ export function delegate(events) {
}
/**
* @param {Node} handler_element
* @param {EventTarget} handler_element
* @param {Event} event
* @returns {void}
*/
export function handle_event_propagation(handler_element, event) {
var owner_document = handler_element.ownerDocument;
var owner_document = /** @type {Node} */ (handler_element).ownerDocument;
var event_name = event.type;
var path = event.composedPath?.() || [];
var current_target = /** @type {null | Element} */ (path[0] || event.target);

@ -0,0 +1,28 @@
import { on } from 'svelte/events';
// ---------------- on
on(document.body, 'click', (e) => e.button);
on(
document.body,
'clidck',
(e) =>
// @ts-expect-error
e.button
);
on(
window,
'click',
(e) =>
// @ts-expect-error ideally we'd know this is a MouseEvent here, too, but for keeping the types sane, we currently don't
e.button
);
on(
// @ts-expect-error
'asd',
'asd',
(e) => e
);

@ -19,6 +19,7 @@
"svelte": ["./src/index.d.ts"],
"svelte/action": ["./src/action/public.d.ts"],
"svelte/compiler": ["./src/compiler/public.d.ts"],
"svelte/events": ["./src/events/index.js"],
"svelte/internal/client": ["./src/internal/client/index.js"],
"svelte/legacy": ["./src/legacy/legacy-client.js"],
"svelte/motion": ["./src/motion/public.d.ts"],

@ -2350,9 +2350,15 @@ declare module 'svelte/events' {
* rather than `addEventListener` will preserve the correct order relative to handlers added declaratively
* (with attributes like `onclick`), which use event delegation for performance reasons
*
*
*/
export function on(element: Element, type: string, handler: EventListener, options?: AddEventListenerOptions | undefined): () => void;
* */
export function on<Element extends HTMLElement, Type extends keyof HTMLElementEventMap>(element: Element, type: Type, handler: (this: Element, event: HTMLElementEventMap[Type]) => any, options?: AddEventListenerOptions | undefined): () => void;
/**
* Attaches an event handler to an element and returns a function that removes the handler. Using this
* rather than `addEventListener` will preserve the correct order relative to handlers added declaratively
* (with attributes like `onclick`), which use event delegation for performance reasons
*
* */
export function on(element: EventTarget, type: string, handler: EventListener, options?: AddEventListenerOptions | undefined): () => void;
}
declare module 'svelte/types/compiler/preprocess' {

Loading…
Cancel
Save