Skip to content

refactor(language-core): generate the type of slots with function property #5173

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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