Skip to content

Commit

Permalink
refactor(language-core): generate the type of slots with function pro…
Browse files Browse the repository at this point in the history
…perty (#5173)
  • Loading branch information
KazariEX authored Feb 12, 2025
1 parent a7bcc1a commit 7da8b85
Show file tree
Hide file tree
Showing 18 changed files with 58 additions and 51 deletions.
10 changes: 5 additions & 5 deletions packages/language-core/lib/codegen/template/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ function* generateSlots(
ctx: TemplateCodegenContext
): Generator<Code> {
if (!options.hasDefineSlots) {
yield `var __VLS_slots!: `;
yield `var __VLS_slots!: __VLS_PrettifyGlobal<{}`;
for (const { expVar, varName } of ctx.dynamicSlots) {
ctx.hasSlot = true;
yield `Partial<Record<NonNullable<typeof ${expVar}>, (_: typeof ${varName}) => any>> &${newLine}`;
yield `${newLine}& { [K in NonNullable<typeof ${expVar}>]?: (props: typeof ${varName}) => any }`;
}
yield `{${newLine}`;
for (const slot of ctx.slots) {
yield `${newLine}& { `;
ctx.hasSlot = true;
if (slot.name && slot.loc !== undefined) {
yield* generateObjectProperty(
Expand All @@ -94,9 +94,9 @@ function* generateSlots(
`default`
);
}
yield `?(_: typeof ${slot.varName}): any,${newLine}`;
yield `?: (props: typeof ${slot.varName}) => any }`;
}
yield `}${endOfLine}`;
yield `>${endOfLine}`;
}
return `typeof ${options.slotsAssignName ?? `__VLS_slots`}`;
}
Expand Down
52 changes: 29 additions & 23 deletions packages/tsc/tests/__snapshots__/dts.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ declare const _default: <Row extends BaseRow>(__VLS_props: NonNullable<Awaited<t
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
attrs: any;
slots: {
default?(_: {
default?: (props: {
row: Row;
}): any;
}) => any;
};
emit: {};
}>) => import("vue").VNode & {
Expand Down Expand Up @@ -99,13 +99,13 @@ exports[`vue-tsc-dts > Input: generic/component.vue, Output: generic/component.v
}>): void;
attrs: any;
slots: Readonly<{
default?(data: {
default?: (props: {
foo: number;
}): any;
}) => any;
}> & {
default?(data: {
default?: (props: {
foo: number;
}): any;
}) => any;
};
emit: ((e: "bar", data: number) => void) & ((evt: "update:title", value: string) => void);
}>) => import("vue").VNode & {
Expand Down Expand Up @@ -133,13 +133,13 @@ exports[`vue-tsc-dts > Input: generic/custom-extension-component.cext, Output: g
}>): void;
attrs: any;
slots: Readonly<{
default?(data: {
default?: (props: {
foo: number;
}): any;
}) => any;
}> & {
default?(data: {
default?: (props: {
foo: number;
}): any;
}) => any;
};
emit: ((e: "bar", data: number) => void) & ((evt: "update:title", value: string) => void);
}>) => import("vue").VNode & {
Expand Down Expand Up @@ -605,12 +605,15 @@ declare var __VLS_3: {
num: number;
str: string;
};
declare var __VLS_slots: {
'no-bind'?(_: typeof __VLS_0): any;
default?(_: typeof __VLS_1): any;
'named-slot'?(_: typeof __VLS_2): any;
vbind?(_: typeof __VLS_3): any;
};
declare var __VLS_slots: __VLS_PrettifyGlobal<{} & {
'no-bind'?: (props: typeof __VLS_0) => any;
} & {
default?: (props: typeof __VLS_1) => any;
} & {
'named-slot'?: (props: typeof __VLS_2) => any;
} & {
vbind?: (props: typeof __VLS_3) => any;
}>;
type __VLS_TemplateSlots = typeof __VLS_slots;
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>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateSlots>;
Expand All @@ -624,7 +627,7 @@ type __VLS_WithTemplateSlots<T, S> = T & {
`;
exports[`vue-tsc-dts > Input: template-slots/component-define-slots.vue, Output: template-slots/component-define-slots.vue.d.ts 1`] = `
"import { VNode } from 'vue';
"import type { VNode } from 'vue';
declare const __VLS_slots: Readonly<{
default: (props: {
num: number;
Expand Down Expand Up @@ -696,12 +699,15 @@ declare var __VLS_3: {
num: number;
str: string;
};
declare var __VLS_slots: {
'no-bind'?(_: typeof __VLS_0): any;
default?(_: typeof __VLS_1): any;
'named-slot'?(_: typeof __VLS_2): any;
vbind?(_: typeof __VLS_3): any;
};
declare var __VLS_slots: __VLS_PrettifyGlobal<{} & {
'no-bind'?: (props: typeof __VLS_0) => any;
} & {
default?: (props: typeof __VLS_1) => any;
} & {
'named-slot'?: (props: typeof __VLS_2) => any;
} & {
vbind?: (props: typeof __VLS_3) => any;
}>;
type __VLS_TemplateSlots = typeof __VLS_slots;
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>;
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateSlots>;
Expand Down
2 changes: 1 addition & 1 deletion test-workspace/component-meta/generic/component.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
defineProps<{ foo: number }>();
defineEmits<{ (e: 'bar', data: number): void }>();
defineExpose({ baz: {} as number });
defineSlots<{ default?(data: { foo: number }): any }>();
defineSlots<{ default?: (props: { foo: number }) => any }>();
defineModel<string>('title');
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
defineProps<{ foo: number }>();
defineEmits<{ (e: 'bar', data: number): void }>();
defineExpose({ baz: {} as number });
defineSlots<{ default?(data: { foo: number }): any }>();
defineSlots<{ default?: (props: { foo: number }) => any }>();
defineModel<string>('title');
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
</template>

<script setup lang="ts">
import { VNode, defineSlots } from 'vue'
import type { VNode } from 'vue'
defineSlots<{
default: (props: {num: number}) => VNode[],
'named-slot': (props: {str: string}) => VNode[],
vbind: (props: {num: number, str: string}) => VNode[],
default: (props: { num: number }) => VNode[],
'named-slot': (props: { str: string }) => VNode[],
vbind: (props: { num: number, str: string }) => VNode[],
'no-bind': () => VNode[],
}>()
</script>
2 changes: 1 addition & 1 deletion test-workspace/tsc/passedFixtures/#2472/generic.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts" generic="T">
defineSlots<{
activator?(props: { isActive: boolean }): void
activator?: (props: { isActive: boolean }) => void
}>();
</script>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ declare const ScriptSetupGenericExact: <T, >(
foo: T;
} & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps,
attrs: any,
slots: Readonly<{ default?(data: T): any; }> & { default?(data: T): any; },
slots: Readonly<{ default?: (props: T) => any; }> & { default?: (props: T) => any; },
emit: { (e: 'bar', data: T): void; },
expose(_exposed: import('vue').ShallowUnwrapRef<{ baz: T; buz: import('vue').Ref<1>; }>): void,
}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import { Ref } from 'vue';
defineProps<{ foo: T }>();
defineEmits<{ (e: 'bar', data: T): void }>();
defineExpose({ baz: {} as T, buz: {} as Ref<1> });
defineSlots<{ default?(data: T): any }>();
defineSlots<{ default?: (props: T) => any }>();
</script>
4 changes: 2 additions & 2 deletions test-workspace/tsc/passedFixtures/vue3/#3371/main.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
defineSlots<{
content(): any;
prop(props: { foo: string }): any;
content: () => any;
prop: (props: { foo: string }) => any;
}>();
</script>

Expand Down
2 changes: 1 addition & 1 deletion test-workspace/tsc/passedFixtures/vue3/#3561/child.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ defineProps<{
}>();
defineSlots<{
default(props: { item: T }): any;
default: (props: { item: T }) => any;
}>();
</script>
4 changes: 3 additions & 1 deletion test-workspace/tsc/passedFixtures/vue3/#3671/main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
</template>

<script lang="ts" setup generic="T extends string">
const slots = defineSlots<Record<T, () => any> & { footer(props: { id: number; }): any; }>();
const slots = defineSlots<Record<T, () => any> & {
footer: (props: { id: number; }) => any;
}>();
</script>
2 changes: 1 addition & 1 deletion test-workspace/tsc/passedFixtures/vue3/#4263/main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<script setup lang="ts">
declare const SomeComponent: new () => {
$slots: {
item(props: {}): any;
item: (props: {}) => any;
};
};
</script>
2 changes: 1 addition & 1 deletion test-workspace/tsc/passedFixtures/vue3/#4327/main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const vTest: ObjectDirective<HTMLElement, any | undefined> = {
};
defineSlots<{
default(): any;
default: () => any;
}>();
</script>

Expand Down
2 changes: 1 addition & 1 deletion test-workspace/tsc/passedFixtures/vue3/#4979/main.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
defineSlots<{
default(props: { foo: string }): any;
default: (props: { foo: string }) => any;
}>();
</script>

Expand Down
2 changes: 1 addition & 1 deletion test-workspace/tsc/passedFixtures/vue3/components/main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ declare const ScriptSetupGenericExact: <T, >(
foo: T;
} & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps,
attrs: any,
slots: Readonly<{ default?(data: T): any; }> & { default?(data: T): any; },
slots: Readonly<{ default?: (props: T) => any; }> & { default?: (props: T) => any; },
emit: { (e: 'bar', data: T): void; },
expose(_exposed: import('vue').ShallowUnwrapRef<{ baz: T; buz: import('vue').Ref<1>; }>): void,
}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import { Ref } from 'vue';
defineProps<{ foo: T }>();
defineEmits<{ (e: 'bar', data: T): void }>();
defineExpose({ baz: {} as T, buz: {} as Ref<1> });
defineSlots<{ default?(data: T): any }>();
defineSlots<{ default?: (props: T) => any }>();
</script>
7 changes: 3 additions & 4 deletions test-workspace/tsc/passedFixtures/vue3/slots/main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default { name: 'Self' };
declare const Comp: new <T>(props: { value: T; }) => {
$props: typeof props;
$slots: {
foo: (_: T) => VNode[];
foo: (props: T) => VNode[];
},
};
</script>
Expand All @@ -44,8 +44,7 @@ const baz = ref('baz' as const);
const slots = useSlots();
exactType(slots, {} as {
bar?(_: { str: string; num: number; }): any;
} & {
baz?(_: { str: string; num: number; }): any;
bar?: (props: { str: string; num: number; }) => any;
baz?: (props: { str: string; num: number; }) => any;
});
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ref } from 'vue';
const foo = ref('bar');
defineSlots<{
default: (_: {
default: (props: {
foo: string;
buz?: number;
}) => any;
Expand Down

0 comments on commit 7da8b85

Please sign in to comment.