Skip to content

Commit 7da8b85

Browse files
authored
refactor(language-core): generate the type of slots with function property (#5173)
1 parent a7bcc1a commit 7da8b85

File tree

18 files changed

+58
-51
lines changed

18 files changed

+58
-51
lines changed

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

+5-5
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,13 @@ function* generateSlots(
6868
ctx: TemplateCodegenContext
6969
): Generator<Code> {
7070
if (!options.hasDefineSlots) {
71-
yield `var __VLS_slots!: `;
71+
yield `var __VLS_slots!: __VLS_PrettifyGlobal<{}`;
7272
for (const { expVar, varName } of ctx.dynamicSlots) {
7373
ctx.hasSlot = true;
74-
yield `Partial<Record<NonNullable<typeof ${expVar}>, (_: typeof ${varName}) => any>> &${newLine}`;
74+
yield `${newLine}& { [K in NonNullable<typeof ${expVar}>]?: (props: typeof ${varName}) => any }`;
7575
}
76-
yield `{${newLine}`;
7776
for (const slot of ctx.slots) {
77+
yield `${newLine}& { `;
7878
ctx.hasSlot = true;
7979
if (slot.name && slot.loc !== undefined) {
8080
yield* generateObjectProperty(
@@ -94,9 +94,9 @@ function* generateSlots(
9494
`default`
9595
);
9696
}
97-
yield `?(_: typeof ${slot.varName}): any,${newLine}`;
97+
yield `?: (props: typeof ${slot.varName}) => any }`;
9898
}
99-
yield `}${endOfLine}`;
99+
yield `>${endOfLine}`;
100100
}
101101
return `typeof ${options.slotsAssignName ?? `__VLS_slots`}`;
102102
}

packages/tsc/tests/__snapshots__/dts.spec.ts.snap

+29-23
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ declare const _default: <Row extends BaseRow>(__VLS_props: NonNullable<Awaited<t
1212
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
1313
attrs: any;
1414
slots: {
15-
default?(_: {
15+
default?: (props: {
1616
row: Row;
17-
}): any;
17+
}) => any;
1818
};
1919
emit: {};
2020
}>) => import("vue").VNode & {
@@ -99,13 +99,13 @@ exports[`vue-tsc-dts > Input: generic/component.vue, Output: generic/component.v
9999
}>): void;
100100
attrs: any;
101101
slots: Readonly<{
102-
default?(data: {
102+
default?: (props: {
103103
foo: number;
104-
}): any;
104+
}) => any;
105105
}> & {
106-
default?(data: {
106+
default?: (props: {
107107
foo: number;
108-
}): any;
108+
}) => any;
109109
};
110110
emit: ((e: "bar", data: number) => void) & ((evt: "update:title", value: string) => void);
111111
}>) => import("vue").VNode & {
@@ -133,13 +133,13 @@ exports[`vue-tsc-dts > Input: generic/custom-extension-component.cext, Output: g
133133
}>): void;
134134
attrs: any;
135135
slots: Readonly<{
136-
default?(data: {
136+
default?: (props: {
137137
foo: number;
138-
}): any;
138+
}) => any;
139139
}> & {
140-
default?(data: {
140+
default?: (props: {
141141
foo: number;
142-
}): any;
142+
}) => any;
143143
};
144144
emit: ((e: "bar", data: number) => void) & ((evt: "update:title", value: string) => void);
145145
}>) => import("vue").VNode & {
@@ -605,12 +605,15 @@ declare var __VLS_3: {
605605
num: number;
606606
str: string;
607607
};
608-
declare var __VLS_slots: {
609-
'no-bind'?(_: typeof __VLS_0): any;
610-
default?(_: typeof __VLS_1): any;
611-
'named-slot'?(_: typeof __VLS_2): any;
612-
vbind?(_: typeof __VLS_3): any;
613-
};
608+
declare var __VLS_slots: __VLS_PrettifyGlobal<{} & {
609+
'no-bind'?: (props: typeof __VLS_0) => any;
610+
} & {
611+
default?: (props: typeof __VLS_1) => any;
612+
} & {
613+
'named-slot'?: (props: typeof __VLS_2) => any;
614+
} & {
615+
vbind?: (props: typeof __VLS_3) => any;
616+
}>;
614617
type __VLS_TemplateSlots = typeof __VLS_slots;
615618
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
616619
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateSlots>;
@@ -624,7 +627,7 @@ type __VLS_WithTemplateSlots<T, S> = T & {
624627
`;
625628
626629
exports[`vue-tsc-dts > Input: template-slots/component-define-slots.vue, Output: template-slots/component-define-slots.vue.d.ts 1`] = `
627-
"import { VNode } from 'vue';
630+
"import type { VNode } from 'vue';
628631
declare const __VLS_slots: Readonly<{
629632
default: (props: {
630633
num: number;
@@ -696,12 +699,15 @@ declare var __VLS_3: {
696699
num: number;
697700
str: string;
698701
};
699-
declare var __VLS_slots: {
700-
'no-bind'?(_: typeof __VLS_0): any;
701-
default?(_: typeof __VLS_1): any;
702-
'named-slot'?(_: typeof __VLS_2): any;
703-
vbind?(_: typeof __VLS_3): any;
704-
};
702+
declare var __VLS_slots: __VLS_PrettifyGlobal<{} & {
703+
'no-bind'?: (props: typeof __VLS_0) => any;
704+
} & {
705+
default?: (props: typeof __VLS_1) => any;
706+
} & {
707+
'named-slot'?: (props: typeof __VLS_2) => any;
708+
} & {
709+
vbind?: (props: typeof __VLS_3) => any;
710+
}>;
705711
type __VLS_TemplateSlots = typeof __VLS_slots;
706712
declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
707713
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateSlots>;

test-workspace/component-meta/generic/component.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
defineProps<{ foo: number }>();
33
defineEmits<{ (e: 'bar', data: number): void }>();
44
defineExpose({ baz: {} as number });
5-
defineSlots<{ default?(data: { foo: number }): any }>();
5+
defineSlots<{ default?: (props: { foo: number }) => any }>();
66
defineModel<string>('title');
77
</script>

test-workspace/component-meta/generic/custom-extension-component.cext

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
defineProps<{ foo: number }>();
33
defineEmits<{ (e: 'bar', data: number): void }>();
44
defineExpose({ baz: {} as number });
5-
defineSlots<{ default?(data: { foo: number }): any }>();
5+
defineSlots<{ default?: (props: { foo: number }) => any }>();
66
defineModel<string>('title');
77
</script>

test-workspace/component-meta/template-slots/component-define-slots.vue

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
</template>
44

55
<script setup lang="ts">
6-
import { VNode, defineSlots } from 'vue'
6+
import type { VNode } from 'vue'
77
88
defineSlots<{
9-
default: (props: {num: number}) => VNode[],
10-
'named-slot': (props: {str: string}) => VNode[],
11-
vbind: (props: {num: number, str: string}) => VNode[],
9+
default: (props: { num: number }) => VNode[],
10+
'named-slot': (props: { str: string }) => VNode[],
11+
vbind: (props: { num: number, str: string }) => VNode[],
1212
'no-bind': () => VNode[],
1313
}>()
1414
</script>

test-workspace/tsc/passedFixtures/#2472/generic.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts" generic="T">
22
defineSlots<{
3-
activator?(props: { isActive: boolean }): void
3+
activator?: (props: { isActive: boolean }) => void
44
}>();
55
</script>
66

test-workspace/tsc/passedFixtures/vue3.4/components/main.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ declare const ScriptSetupGenericExact: <T, >(
7575
foo: T;
7676
} & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps,
7777
attrs: any,
78-
slots: Readonly<{ default?(data: T): any; }> & { default?(data: T): any; },
78+
slots: Readonly<{ default?: (props: T) => any; }> & { default?: (props: T) => any; },
7979
emit: { (e: 'bar', data: T): void; },
8080
expose(_exposed: import('vue').ShallowUnwrapRef<{ baz: T; buz: import('vue').Ref<1>; }>): void,
8181
}>

test-workspace/tsc/passedFixtures/vue3.4/components/script-setup-generic.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ import { Ref } from 'vue';
44
defineProps<{ foo: T }>();
55
defineEmits<{ (e: 'bar', data: T): void }>();
66
defineExpose({ baz: {} as T, buz: {} as Ref<1> });
7-
defineSlots<{ default?(data: T): any }>();
7+
defineSlots<{ default?: (props: T) => any }>();
88
</script>

test-workspace/tsc/passedFixtures/vue3/#3371/main.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script setup lang="ts">
22
defineSlots<{
3-
content(): any;
4-
prop(props: { foo: string }): any;
3+
content: () => any;
4+
prop: (props: { foo: string }) => any;
55
}>();
66
</script>
77

test-workspace/tsc/passedFixtures/vue3/#3561/child.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ defineProps<{
66
}>();
77
88
defineSlots<{
9-
default(props: { item: T }): any;
9+
default: (props: { item: T }) => any;
1010
}>();
1111
</script>

test-workspace/tsc/passedFixtures/vue3/#3671/main.vue

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33
</template>
44

55
<script lang="ts" setup generic="T extends string">
6-
const slots = defineSlots<Record<T, () => any> & { footer(props: { id: number; }): any; }>();
6+
const slots = defineSlots<Record<T, () => any> & {
7+
footer: (props: { id: number; }) => any;
8+
}>();
79
</script>

test-workspace/tsc/passedFixtures/vue3/#4263/main.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<script setup lang="ts">
2121
declare const SomeComponent: new () => {
2222
$slots: {
23-
item(props: {}): any;
23+
item: (props: {}) => any;
2424
};
2525
};
2626
</script>

test-workspace/tsc/passedFixtures/vue3/#4327/main.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const vTest: ObjectDirective<HTMLElement, any | undefined> = {
66
};
77
88
defineSlots<{
9-
default(): any;
9+
default: () => any;
1010
}>();
1111
</script>
1212

test-workspace/tsc/passedFixtures/vue3/#4979/main.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
22
defineSlots<{
3-
default(props: { foo: string }): any;
3+
default: (props: { foo: string }) => any;
44
}>();
55
</script>
66

test-workspace/tsc/passedFixtures/vue3/components/main.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ declare const ScriptSetupGenericExact: <T, >(
7474
foo: T;
7575
} & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps,
7676
attrs: any,
77-
slots: Readonly<{ default?(data: T): any; }> & { default?(data: T): any; },
77+
slots: Readonly<{ default?: (props: T) => any; }> & { default?: (props: T) => any; },
7878
emit: { (e: 'bar', data: T): void; },
7979
expose(_exposed: import('vue').ShallowUnwrapRef<{ baz: T; buz: import('vue').Ref<1>; }>): void,
8080
}>

test-workspace/tsc/passedFixtures/vue3/components/script-setup-generic.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ import { Ref } from 'vue';
44
defineProps<{ foo: T }>();
55
defineEmits<{ (e: 'bar', data: T): void }>();
66
defineExpose({ baz: {} as T, buz: {} as Ref<1> });
7-
defineSlots<{ default?(data: T): any }>();
7+
defineSlots<{ default?: (props: T) => any }>();
88
</script>

test-workspace/tsc/passedFixtures/vue3/slots/main.vue

+3-4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export default { name: 'Self' };
3131
declare const Comp: new <T>(props: { value: T; }) => {
3232
$props: typeof props;
3333
$slots: {
34-
foo: (_: T) => VNode[];
34+
foo: (props: T) => VNode[];
3535
},
3636
};
3737
</script>
@@ -44,8 +44,7 @@ const baz = ref('baz' as const);
4444
4545
const slots = useSlots();
4646
exactType(slots, {} as {
47-
bar?(_: { str: string; num: number; }): any;
48-
} & {
49-
baz?(_: { str: string; num: number; }): any;
47+
bar?: (props: { str: string; num: number; }) => any;
48+
baz?: (props: { str: string; num: number; }) => any;
5049
});
5150
</script>

test-workspace/tsc/passedFixtures/vue3_strictTemplate/#2726/main.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ref } from 'vue';
44
const foo = ref('bar');
55
66
defineSlots<{
7-
default: (_: {
7+
default: (props: {
88
foo: string;
99
buz?: number;
1010
}) => any;

0 commit comments

Comments
 (0)