diff --git a/packages-private/dts-test/h.test-d.ts b/packages-private/dts-test/h.test-d.ts index a199e14ced9..ebe127ff663 100644 --- a/packages-private/dts-test/h.test-d.ts +++ b/packages-private/dts-test/h.test-d.ts @@ -39,6 +39,51 @@ describe('h inference w/ element', () => { onClick: e => { expectType(e) }, + onClickCapture: e => { + expectType(e) + }, + onClickCaptureOnce: e => { + expectType(e) + }, + onClickCaptureOncePassive: e => { + expectType(e) + }, + onClickCapturePassive: e => { + expectType(e) + }, + onClickCapturePassiveOnce: e => { + expectType(e) + }, + onClickOnce: e => { + expectType(e) + }, + onClickOnceCapture: e => { + expectType(e) + }, + onClickOnceCapturePassive: e => { + expectType(e) + }, + onClickOncePassive: e => { + expectType(e) + }, + onClickOncePassiveCapture: e => { + expectType(e) + }, + onClickPassive: e => { + expectType(e) + }, + onClickPassiveCapture: e => { + expectType(e) + }, + onClickPassiveCaptureOnce: e => { + expectType(e) + }, + onClickPassiveOnce: e => { + expectType(e) + }, + onClickPassiveOnceCapture: e => { + expectType(e) + }, }) h('input', { onFocus(e) { diff --git a/packages-private/dts-test/tsx.test-d.tsx b/packages-private/dts-test/tsx.test-d.tsx index 0cd380f0447..c1c6fc75ec6 100644 --- a/packages-private/dts-test/tsx.test-d.tsx +++ b/packages-private/dts-test/tsx.test-d.tsx @@ -84,6 +84,52 @@ expectType( // infer correct event type expectType(e.target) }} + onInputCapture={e => { + expectType(e.target) + }} + onInputCaptureOnce={e => { + expectType(e.target) + }} + onInputCaptureOncePassive={e => { + expectType(e.target) + }} + onInputCapturePassive={e => { + expectType(e.target) + }} + onInputCapturePassiveOnce={e => { + expectType(e.target) + }} + onInputOnce={e => { + expectType(e.target) + }} + onInputOnceCapture={e => { + expectType(e.target) + }} + onInputOnceCapturePassive={e => { + expectType(e.target) + }} + onInputOncePassive={e => { + expectType(e.target) + }} + onInputOncePassiveCapture={e => { + expectType(e.target) + }} + onInputPassive={e => { + // infer correct event type + expectType(e.target) + }} + onInputPassiveCapture={e => { + expectType(e.target) + }} + onInputPassiveCaptureOnce={e => { + expectType(e.target) + }} + onInputPassiveOnce={e => { + expectType(e.target) + }} + onInputPassiveOnceCapture={e => { + expectType(e.target) + }} />, ) diff --git a/packages/runtime-core/src/h.ts b/packages/runtime-core/src/h.ts index 93e7fd9bc88..b3b4c8eef06 100644 --- a/packages/runtime-core/src/h.ts +++ b/packages/runtime-core/src/h.ts @@ -75,8 +75,14 @@ interface Constructor

{ new (...args: any[]): { $props: P } } +type CombineModifiers = T extends any + ? T | `${T}${CombineModifiers>}` + : never + +type EventModifiers = CombineModifiers<'Capture' | 'Once' | 'Passive'> | '' + type HTMLElementEventHandler = { - [K in keyof HTMLElementEventMap as `on${Capitalize}`]?: ( + [K in keyof HTMLElementEventMap as `on${Capitalize}${EventModifiers}`]?: ( ev: HTMLElementEventMap[K], ) => any } diff --git a/packages/runtime-dom/src/jsx.ts b/packages/runtime-dom/src/jsx.ts index 5292441cde9..f32d80d31d2 100644 --- a/packages/runtime-dom/src/jsx.ts +++ b/packages/runtime-dom/src/jsx.ts @@ -252,7 +252,7 @@ export type StyleValue = | CSSProperties | Array -export interface HTMLAttributes extends AriaAttributes, EventHandlers { +export interface HTMLAttributes extends AriaAttributes, EventHandlers { innerHTML?: string class?: any @@ -808,7 +808,7 @@ export interface WebViewHTMLAttributes extends HTMLAttributes { webpreferences?: string } -export interface SVGAttributes extends AriaAttributes, EventHandlers { +export interface SVGAttributes extends AriaAttributes, EventHandlers { innerHTML?: string /** @@ -1384,10 +1384,14 @@ export interface Events { onTransitionstart: TransitionEvent } -type EventHandlers = { - [K in keyof E]?: E[K] extends (...args: any) => any - ? E[K] - : (payload: E[K]) => void +type CombineModifiers = T extends any + ? T | `${T}${CombineModifiers>}` + : never + +type EventModifiers = CombineModifiers<'Capture' | 'Once' | 'Passive'> | '' + +type EventHandlers = { + [K in keyof Events as `${K}${EventModifiers}`]?: (payload: Events[K]) => void } import type { VNodeRef } from '@vue/runtime-core'