1
- import type { EmitFn , HTMLAttributes , ObjectEmitsOptions , PublicProps } from 'vue'
1
+ import { type EmitFn , type HTMLAttributes , type PublicProps } from 'vue'
2
2
3
3
// Select the properties to expose to template type checking.
4
4
type KitchenSinkAttributes = 'foo' | 'bar'
@@ -20,28 +20,45 @@ export class SomeEvent extends Event {
20
20
}
21
21
}
22
22
23
- type DefineCustomElement <
24
- T extends HTMLElement ,
25
- Attributes extends keyof T = keyof T ,
26
- Events extends ObjectEmitsOptions = { } ,
27
- > = new ( ) => T & {
28
- // Use this to define the properties exposed to template type checking.
29
- /** @deprecated Do not use the $props property on a Custom Element ref, this is for template prop types only. */
30
- $props : HTMLAttributes & Partial < Pick < T , Attributes > > & PublicProps
31
-
32
- // Use this to define specifically the event properties exposed to template type checking.
33
- /** @deprecated Do not use the $emit property on a Custom Element ref, this is for template prop types only. */
34
- $emit : EmitFn < Events >
35
-
36
- // /** @deprecated Do not use the $attrs property on an element ref, this is for template prop types only. */
37
- // $attrs: {[x: string]: string}
23
+ type KitchenSinkEvents = {
24
+ 'some-event' : SomeEvent
38
25
}
39
26
40
27
customElements . define ( 'kitchen-sink' , KitchenSink )
41
28
42
29
declare module 'vue' {
43
30
interface GlobalComponents {
44
31
// Use the helper to add any custom element to GlobalComponents.
45
- 'kitchen-sink' : DefineCustomElement < KitchenSink , KitchenSinkAttributes , { 'some-event' : ( e : SomeEvent ) => void } >
32
+ 'kitchen-sink' : DefineCustomElement < KitchenSink , KitchenSinkEvents , KitchenSinkAttributes >
46
33
}
47
34
}
35
+
36
+ // helper for Vue type definitions /////////////////////////////////////////////////////////
37
+
38
+ type DefineCustomElement <
39
+ ElementType extends HTMLElement ,
40
+ Events extends EventMap = { } ,
41
+ SelectedAttributes extends keyof ElementType = keyof ElementType ,
42
+ > = new ( ) => ElementType & {
43
+ // Use $props to define the properties exposed to template type checking. Vue
44
+ // specifically reads prop definitions from the `$props` type. Note that we
45
+ // combine the element's props with the global HTML props and Vue's special
46
+ // props.
47
+ /** @deprecated Do not use the $props property on a Custom Element ref, this is for template prop types only. */
48
+ $props : HTMLAttributes & Partial < Pick < ElementType , SelectedAttributes > > & PublicProps
49
+
50
+ // Use $emit to specifically define event types. Vue specifically reads event
51
+ // types from the `$emit` type. Note that `$emit` expects a particular format
52
+ // that we map `Events` to.
53
+ /** @deprecated Do not use the $emit property on a Custom Element ref, this is for template prop types only. */
54
+ $emit : VueEmit < Events >
55
+ }
56
+
57
+ type EventMap = {
58
+ [ event : string ] : Event
59
+ }
60
+
61
+ // This maps an EventMap to the format that Vue's $emit type expects.
62
+ type VueEmit < T extends EventMap > = EmitFn < {
63
+ [ K in keyof T ] : ( event : T [ K ] ) => void
64
+ } >
0 commit comments