This commit is contained in:
Валентин Степанов 2025-06-19 14:14:53 +08:00 committed by GitHub
commit 4695b36e82
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 108 additions and 7 deletions

View File

@ -39,6 +39,51 @@ describe('h inference w/ element', () => {
onClick: e => {
expectType<MouseEvent>(e)
},
onClickCapture: e => {
expectType<MouseEvent>(e)
},
onClickCaptureOnce: e => {
expectType<MouseEvent>(e)
},
onClickCaptureOncePassive: e => {
expectType<MouseEvent>(e)
},
onClickCapturePassive: e => {
expectType<MouseEvent>(e)
},
onClickCapturePassiveOnce: e => {
expectType<MouseEvent>(e)
},
onClickOnce: e => {
expectType<MouseEvent>(e)
},
onClickOnceCapture: e => {
expectType<MouseEvent>(e)
},
onClickOnceCapturePassive: e => {
expectType<MouseEvent>(e)
},
onClickOncePassive: e => {
expectType<MouseEvent>(e)
},
onClickOncePassiveCapture: e => {
expectType<MouseEvent>(e)
},
onClickPassive: e => {
expectType<MouseEvent>(e)
},
onClickPassiveCapture: e => {
expectType<MouseEvent>(e)
},
onClickPassiveCaptureOnce: e => {
expectType<MouseEvent>(e)
},
onClickPassiveOnce: e => {
expectType<MouseEvent>(e)
},
onClickPassiveOnceCapture: e => {
expectType<MouseEvent>(e)
},
})
h('input', {
onFocus(e) {

View File

@ -84,6 +84,52 @@ expectType<JSX.Element>(
// infer correct event type
expectType<EventTarget | null>(e.target)
}}
onInputCapture={e => {
expectType<EventTarget | null>(e.target)
}}
onInputCaptureOnce={e => {
expectType<EventTarget | null>(e.target)
}}
onInputCaptureOncePassive={e => {
expectType<EventTarget | null>(e.target)
}}
onInputCapturePassive={e => {
expectType<EventTarget | null>(e.target)
}}
onInputCapturePassiveOnce={e => {
expectType<EventTarget | null>(e.target)
}}
onInputOnce={e => {
expectType<EventTarget | null>(e.target)
}}
onInputOnceCapture={e => {
expectType<EventTarget | null>(e.target)
}}
onInputOnceCapturePassive={e => {
expectType<EventTarget | null>(e.target)
}}
onInputOncePassive={e => {
expectType<EventTarget | null>(e.target)
}}
onInputOncePassiveCapture={e => {
expectType<EventTarget | null>(e.target)
}}
onInputPassive={e => {
// infer correct event type
expectType<EventTarget | null>(e.target)
}}
onInputPassiveCapture={e => {
expectType<EventTarget | null>(e.target)
}}
onInputPassiveCaptureOnce={e => {
expectType<EventTarget | null>(e.target)
}}
onInputPassiveOnce={e => {
expectType<EventTarget | null>(e.target)
}}
onInputPassiveOnceCapture={e => {
expectType<EventTarget | null>(e.target)
}}
/>,
)

View File

@ -75,8 +75,14 @@ interface Constructor<P = any> {
new (...args: any[]): { $props: P }
}
type CombineModifiers<T extends string, U extends string = T> = T extends any
? T | `${T}${CombineModifiers<Exclude<U, T>>}`
: never
type EventModifiers = CombineModifiers<'Capture' | 'Once' | 'Passive'> | ''
type HTMLElementEventHandler = {
[K in keyof HTMLElementEventMap as `on${Capitalize<K>}`]?: (
[K in keyof HTMLElementEventMap as `on${Capitalize<K>}${EventModifiers}`]?: (
ev: HTMLElementEventMap[K],
) => any
}

View File

@ -252,7 +252,7 @@ export type StyleValue =
| CSSProperties
| Array<StyleValue>
export interface HTMLAttributes extends AriaAttributes, EventHandlers<Events> {
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<Events> {
export interface SVGAttributes extends AriaAttributes, EventHandlers {
innerHTML?: string
/**
@ -1384,10 +1384,14 @@ export interface Events {
onTransitionstart: TransitionEvent
}
type EventHandlers<E> = {
[K in keyof E]?: E[K] extends (...args: any) => any
? E[K]
: (payload: E[K]) => void
type CombineModifiers<T extends string, U extends string = T> = T extends any
? T | `${T}${CombineModifiers<Exclude<U, T>>}`
: 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'