Skip to content

Commit 22eea60

Browse files
authored
fix(language-core): should preserve generic info in directive (#4686)
1 parent d35cb82 commit 22eea60

File tree

3 files changed

+59
-19
lines changed

3 files changed

+59
-19
lines changed

packages/language-core/lib/codegen/script/globalTypes.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,14 @@ declare global {
5454
function __VLS_getSlotParams<T>(slot: T): Parameters<__VLS_PickNotAny<NonNullable<T>, (...args: any[]) => any>>;
5555
// @ts-ignore
5656
function __VLS_getSlotParam<T>(slot: T): Parameters<__VLS_PickNotAny<NonNullable<T>, (...args: any[]) => any>>[0];
57-
function __VLS_directiveFunction<T>(dir: T):
58-
T extends import('${vueCompilerOptions.lib}').ObjectDirective<infer E, infer V> | import('${vueCompilerOptions.lib}').FunctionDirective<infer E, infer V> ? (value: V) => void
59-
: T;
57+
58+
// Custom Directives
59+
type __VLS_unknownDirective = (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown) => void;
60+
function __VLS_directiveAsFunction<T extends import('${vueCompilerOptions.lib}').Directive>(dir: T): T extends (...args: any) => any
61+
? T | __VLS_unknownDirective
62+
: NonNullable<(T & Record<string, __VLS_unknownDirective>)['created' | 'beforeMount' | 'mounted' | 'beforeUpdate' | 'updated' | 'beforeUnmount' | 'unmounted']>;
63+
const __VLS_directiveBindingRestFields = { instance: null, oldValue: null, modifiers: null as any, dir: null as any };
64+
6065
function __VLS_withScope<T, K>(ctx: T, scope: K): ctx is T & K;
6166
function __VLS_makeOptional<T>(t: T): { [K in keyof T]?: T[K] };
6267
function __VLS_nonNullable<T>(t: T): T extends null | undefined ? never : T;

packages/language-core/lib/codegen/template/elementDirectives.ts

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export function* generateElementDirectives(
4343
prop.loc.start.offset,
4444
prop.loc.end.offset,
4545
ctx.codeFeatures.verification,
46-
`__VLS_directiveFunction(__VLS_ctx.`,
46+
`__VLS_directiveAsFunction(__VLS_ctx.`,
4747
...generateCamelized(
4848
'v-' + prop.name,
4949
prop.loc.start.offset,
@@ -60,27 +60,36 @@ export function* generateElementDirectives(
6060
},
6161
}
6262
),
63-
`)(`,
63+
`)(null!, { ...__VLS_directiveBindingRestFields, `,
6464
...(
6565
prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
66-
? wrapWith(
67-
prop.exp.loc.start.offset,
68-
prop.exp.loc.end.offset,
69-
ctx.codeFeatures.verification,
70-
...generateInterpolation(
71-
options,
72-
ctx,
73-
prop.exp.content,
74-
prop.exp.loc,
66+
? [
67+
...wrapWith(
7568
prop.exp.loc.start.offset,
76-
ctx.codeFeatures.all,
77-
'(',
78-
')'
69+
prop.exp.loc.end.offset,
70+
ctx.codeFeatures.verification,
71+
'value'
72+
),
73+
': ',
74+
...wrapWith(
75+
prop.exp.loc.start.offset,
76+
prop.exp.loc.end.offset,
77+
ctx.codeFeatures.verification,
78+
...generateInterpolation(
79+
options,
80+
ctx,
81+
prop.exp.content,
82+
prop.exp.loc,
83+
prop.exp.loc.start.offset,
84+
ctx.codeFeatures.all,
85+
'(',
86+
')'
87+
)
7988
)
80-
)
89+
]
8190
: [`undefined`]
8291
),
83-
`)`
92+
`}, null!, null!)`
8493
);
8594
yield endOfLine;
8695
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<template>
2+
<div v-object1="[1, (_a: 1) => { }]"></div>
3+
<div v-object2="[1, (_a: 1) => { }]"></div>
4+
<div v-function1="[1, (_a: 1) => { }]"></div>
5+
<div v-function2="[1, (_a: 1) => { }]"></div>
6+
</template>
7+
8+
<script lang="ts" setup>
9+
import { FunctionDirective } from 'vue';
10+
import { ObjectDirective } from 'vue';
11+
12+
const vObject1 = {
13+
created<T extends number>(
14+
_el: HTMLElement,
15+
_binding: { value: [T, (a: T) => void]; }
16+
) { },
17+
mounted<T extends number>(
18+
_el: HTMLElement,
19+
_binding: { value: [T, (a: T) => void]; },
20+
_vNode: any,
21+
) { },
22+
};
23+
const vObject2 = {} as any as ObjectDirective<any, [1, (a: 1) => void]>;
24+
function vFunction1<T extends number>(_el: any, _binding: { value: [T, (a: T) => void]; }) { }
25+
const vFunction2 = {} as any as FunctionDirective<any, [1, (a: 1) => void]>;
26+
</script>

0 commit comments

Comments
 (0)