Skip to content

Commit ca63ffa

Browse files
committed
chore: typed directives + VModel directive
1 parent 08c1217 commit ca63ffa

File tree

2 files changed

+38
-17
lines changed

2 files changed

+38
-17
lines changed

packages/runtime-core/src/directives.ts

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,28 @@ import { currentRenderingInstance } from './componentRenderContext'
1919
import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling'
2020
import { ComponentPublicInstance } from './componentPublicInstance'
2121

22-
export interface DirectiveBinding<V = any> {
22+
export interface DirectiveBinding<
23+
V = any,
24+
Arg extends string = string,
25+
Modifiers extends string = string
26+
> {
2327
instance: ComponentPublicInstance | null
2428
value: V
2529
oldValue: V | null
26-
arg?: string
27-
modifiers: DirectiveModifiers
30+
arg?: Arg
31+
modifiers: DirectiveModifiers<Modifiers>
2832
dir: ObjectDirective<any, V>
2933
}
3034

31-
export type DirectiveHook<T = any, Prev = VNode<any, T> | null, V = any> = (
35+
export type DirectiveHook<
36+
T = any,
37+
Prev = VNode<any, T> | null,
38+
V = any,
39+
Arg extends string = string,
40+
Modifiers extends string = string
41+
> = (
3242
el: T,
33-
binding: DirectiveBinding<V>,
43+
binding: DirectiveBinding<V, Arg, Modifiers>,
3444
vnode: VNode<any, T>,
3545
prevVNode: Prev
3646
) => void
@@ -40,14 +50,19 @@ export type SSRDirectiveHook = (
4050
vnode: VNode
4151
) => Data | undefined
4252

43-
export interface ObjectDirective<T = any, V = any> {
44-
created?: DirectiveHook<T, null, V>
45-
beforeMount?: DirectiveHook<T, null, V>
46-
mounted?: DirectiveHook<T, null, V>
47-
beforeUpdate?: DirectiveHook<T, VNode<any, T>, V>
48-
updated?: DirectiveHook<T, VNode<any, T>, V>
49-
beforeUnmount?: DirectiveHook<T, null, V>
50-
unmounted?: DirectiveHook<T, null, V>
53+
export interface ObjectDirective<
54+
T = any,
55+
V = any,
56+
Arg extends string = string,
57+
Modifiers extends string = string
58+
> {
59+
created?: DirectiveHook<T, null, V, Arg, Modifiers>
60+
beforeMount?: DirectiveHook<T, null, V, Arg, Modifiers>
61+
mounted?: DirectiveHook<T, null, V, Arg, Modifiers>
62+
beforeUpdate?: DirectiveHook<T, VNode<any, T>, V, Arg, Modifiers>
63+
updated?: DirectiveHook<T, VNode<any, T>, V, Arg, Modifiers>
64+
beforeUnmount?: DirectiveHook<T, null, V, Arg, Modifiers>
65+
unmounted?: DirectiveHook<T, null, V, Arg, Modifiers>
5166
getSSRProps?: SSRDirectiveHook
5267
}
5368

@@ -57,7 +72,7 @@ export type Directive<T = any, V = any> =
5772
| ObjectDirective<T, V>
5873
| FunctionDirective<T, V>
5974

60-
export type DirectiveModifiers = Record<string, boolean>
75+
export type DirectiveModifiers<K extends string = string> = Record<K, boolean>
6176

6277
const isBuiltInDirective = /*#__PURE__*/ makeMap(
6378
'bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text'

packages/runtime-dom/src/directives/vModel.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,18 @@ function trigger(el: HTMLElement, type: string) {
4040
el.dispatchEvent(e)
4141
}
4242

43-
type ModelDirective<T> = ObjectDirective<T & { _assign: AssignerFn }>
43+
type ModelDirective<T, Modifiers extends string = string> = ObjectDirective<
44+
T & { _assign: AssignerFn },
45+
any,
46+
string,
47+
Modifiers
48+
>
4449

4550
// We are exporting the v-model runtime directly as vnode hooks so that it can
4651
// be tree-shaken in case v-model is never used.
4752
export const vModelText: ModelDirective<
48-
HTMLInputElement | HTMLTextAreaElement
53+
HTMLInputElement | HTMLTextAreaElement,
54+
'trim' | 'number' | 'lazy'
4955
> = {
5056
created(el, { modifiers: { lazy, trim, number } }, vnode) {
5157
el._assign = getModelAssigner(vnode)
@@ -170,7 +176,7 @@ export const vModelRadio: ModelDirective<HTMLInputElement> = {
170176
}
171177
}
172178

173-
export const vModelSelect: ModelDirective<HTMLSelectElement> = {
179+
export const vModelSelect: ModelDirective<HTMLSelectElement, 'number'> = {
174180
created(el, { value, modifiers: { number } }, vnode) {
175181
const isSetModel = isSet(value)
176182
addEventListener(el, 'change', () => {

0 commit comments

Comments
 (0)