Skip to content

Commit

Permalink
fix(component-meta): defineSlots allows empty params (#4093)
Browse files Browse the repository at this point in the history
  • Loading branch information
Evertvdw authored Mar 20, 2024
1 parent 3758474 commit c09b94c
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/component-meta/lib/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ function createSchemaResolvers(
const propType = typeChecker.getNonNullableType(typeChecker.getTypeOfSymbolAtLocation(prop, symbolNode));
const signatures = propType.getCallSignatures();
const paramType = signatures[0].parameters[0];
const subtype = typeChecker.getTypeOfSymbolAtLocation(paramType, symbolNode);
const subtype = paramType ? typeChecker.getTypeOfSymbolAtLocation(paramType, symbolNode) : typeChecker.getAnyType();
let schema: PropertyMetaSchema;
let declarations: Declaration[];

Expand Down
28 changes: 28 additions & 0 deletions packages/component-meta/tests/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,34 @@ const worker = (checker: ComponentMetaChecker, withTsconfig: boolean) => describ
expect(d).toBeDefined();
});

test('defineSlots', () => {
const componentPath = path.resolve(__dirname, '../../../test-workspace/component-meta/template-slots/component-define-slots.vue');
const meta = checker.getComponentMeta(componentPath);

expect(meta.type).toEqual(TypeMeta.Class);

const a = meta.slots.find(slot =>
slot.name === 'default'
&& slot.type === '{ num: number; }'
);
const b = meta.slots.find(slot =>
slot.name === 'named-slot'
&& slot.type === '{ str: string; }'
);
const c = meta.slots.find(slot =>
slot.name === 'vbind'
&& slot.type === '{ num: number; str: string; }'
);
const d = meta.slots.find(slot =>
slot.name === 'no-bind'
);

expect(a).toBeDefined();
expect(b).toBeDefined();
expect(c).toBeDefined();
expect(d).toBeDefined();
});

test('template-slots for generic', () => {
const componentPath = path.resolve(__dirname, '../../../test-workspace/component-meta/generic/component.vue');
const meta = checker.getComponentMeta(componentPath);
Expand Down
52 changes: 52 additions & 0 deletions packages/tsc/tests/__snapshots__/dts.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,58 @@ 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';
declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>, Readonly<{
default: (props: {
num: number;
}) => VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
'named-slot': (props: {
str: string;
}) => VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
vbind: (props: {
num: number;
str: string;
}) => VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
'no-bind': () => VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
}> & {
default: (props: {
num: number;
}) => VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
'named-slot': (props: {
str: string;
}) => VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
vbind: (props: {
num: number;
str: string;
}) => VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
'no-bind': () => VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
}>;
export default _default;
type __VLS_WithTemplateSlots<T, S> = T & {
new (): {
$slots: S;
};
};
"
`;
exports[`vue-tsc-dts > Input: template-slots/component-no-script.vue, Output: template-slots/component-no-script.vue.d.ts 1`] = `
"declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>, {
"no-bind"?(_: {}): any;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<template>

</template>

<script setup lang="ts">
import { VNode, defineSlots } from 'vue'
defineSlots<{
default: (props: {num: number}) => VNode[],
'named-slot': (props: {str: string}) => VNode[],
vbind: (props: {num: number, str: string}) => VNode[],
'no-bind': () => VNode[],
}>()
</script>

0 comments on commit c09b94c

Please # to comment.