From 31d9dd2a8d3a0676bbcd1ba38fa4c89e862a5f66 Mon Sep 17 00:00:00 2001 From: PINGUET Julien Date: Thu, 30 Nov 2023 14:37:05 +0100 Subject: [PATCH 1/3] fix(component-type-helpers): correct type inference for FunctionalComponent --- packages/component-type-helpers/index.d.ts | 4 ++-- packages/component-type-helpers/index.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/component-type-helpers/index.d.ts b/packages/component-type-helpers/index.d.ts index 0ce45dcf0d..033e56ce51 100644 --- a/packages/component-type-helpers/index.d.ts +++ b/packages/component-type-helpers/index.d.ts @@ -14,12 +14,12 @@ export type ComponentProps = export type ComponentSlots = T extends new () => { $slots: infer S; } ? NonNullable : - T extends (props: any, ctx: { slots: infer S; }, ...args: any) => any ? NonNullable : + T extends (props: any, ctx: { slots: infer S; attrs: any; emit: any; }, ...args: any) => any ? NonNullable : {}; export type ComponentEmit = T extends new () => { $emit: infer E; } ? NonNullable : - T extends (props: any, ctx: { emit: infer E; }, ...args: any) => any ? NonNullable : + T extends (props: any, ctx: { slots: any; attrs: any; emit: infer E; }, ...args: any) => any ? NonNullable : {}; export type ComponentExposed = diff --git a/packages/component-type-helpers/index.js b/packages/component-type-helpers/index.js index 49123c5d9c..90132268f3 100644 --- a/packages/component-type-helpers/index.js +++ b/packages/component-type-helpers/index.js @@ -13,12 +13,12 @@ export type ComponentProps = export type ComponentSlots = T extends new () => { $slots: infer S; } ? NonNullable : - T extends (props: any, ctx: { slots: infer S; }, ...args: any) => any ? NonNullable : + T extends (props: any, ctx: { slots: infer S; attrs: any; emit: any; }, ...args: any) => any ? NonNullable : {}; export type ComponentEmit = T extends new () => { $emit: infer E; } ? NonNullable : - T extends (props: any, ctx: { emit: infer E; }, ...args: any) => any ? NonNullable : + T extends (props: any, ctx: { slots: any; attrs: any; emit: infer E; }, ...args: any) => any ? NonNullable : {}; export type ComponentExposed = From 774d6b3921bea596a16f701f506dbf1fbd450a55 Mon Sep 17 00:00:00 2001 From: PINGUET Julien Date: Thu, 30 Nov 2023 20:45:12 +0100 Subject: [PATCH 2/3] test --- packages/component-meta/tests/index.spec.ts | 25 +++++++++ .../tsc/tests/__snapshots__/dts.spec.ts.snap | 53 +++++++++++++++++++ .../component-meta/generic/component.vue | 6 +++ 3 files changed, 84 insertions(+) create mode 100644 test-workspace/component-meta/generic/component.vue diff --git a/packages/component-meta/tests/index.spec.ts b/packages/component-meta/tests/index.spec.ts index f1f443977e..ac4ac3521a 100644 --- a/packages/component-meta/tests/index.spec.ts +++ b/packages/component-meta/tests/index.spec.ts @@ -535,6 +535,19 @@ const worker = (checker: ComponentMetaChecker, withTsconfig: boolean) => describ expect(onBaz?.schema).toEqual([]); }); + test('reference-type-events for generic', () => { + const componentPath = path.resolve(__dirname, '../../../test-workspace/component-meta/generic/component.vue'); + const meta = checker.getComponentMeta(componentPath); + + expect(meta.type).toEqual(TypeMeta.Function); + + const onBar = meta.events.find(event => event.name === 'bar'); + + expect(onBar).toBeDefined(); + expect(onBar?.type).toEqual('number'); + expect(onBar?.signature).toEqual('(e: "bar", data: number): void'); + }); + test('template-slots', () => { const componentPath = path.resolve(__dirname, '../../../test-workspace/component-meta/template-slots/component.vue'); const meta = checker.getComponentMeta(componentPath); @@ -563,6 +576,18 @@ const worker = (checker: ComponentMetaChecker, withTsconfig: boolean) => describ 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); + + expect(meta.type).toEqual(TypeMeta.Function); + + expect(meta.slots.find(slot => + slot.name === 'default' + && slot.type === '{ foo: number; }' + )).toBeDefined(); + }); + test('template-slots without a script block', () => { const componentPath = path.resolve(__dirname, '../../../test-workspace/component-meta/template-slots/component-no-script.vue'); const meta = checker.getComponentMeta(componentPath); diff --git a/packages/tsc/tests/__snapshots__/dts.spec.ts.snap b/packages/tsc/tests/__snapshots__/dts.spec.ts.snap index 7e5d5676e7..1bbadc6c3a 100644 --- a/packages/tsc/tests/__snapshots__/dts.spec.ts.snap +++ b/packages/tsc/tests/__snapshots__/dts.spec.ts.snap @@ -22,6 +22,59 @@ export default _default; " `; +exports[`vue-tsc-dts > Input: generic/component.vue, Output: generic/component.vue.d.ts 1`] = ` +"declare const _default: (__VLS_props: { + onBar?: (data: number) => any; + foo: number; +} & import(\\"vue\\").VNodeProps & import(\\"vue\\").AllowedComponentProps & import(\\"vue\\").ComponentCustomProps, __VLS_ctx?: { + attrs: any; + emit: (e: 'bar', data: number) => void; + slots: Readonly<{ + default?(data: { + foo: number; + }): any; + }>; +}, __VLS_expose?: (exposed: import(\\"vue\\").ShallowUnwrapRef<{ + baz: number; +}>) => void, __VLS_setup?: Promise<{ + props: { + onBar?: (data: number) => any; + foo: number; + } & import(\\"vue\\").VNodeProps & import(\\"vue\\").AllowedComponentProps & import(\\"vue\\").ComponentCustomProps; + expose(exposed: import(\\"vue\\").ShallowUnwrapRef<{ + baz: number; + }>): void; + attrs: any; + slots: Readonly<{ + default?(data: { + foo: number; + }): any; + }>; + emit: (e: 'bar', data: number) => void; +}>) => import(\\"vue\\").VNode & { + __ctx?: { + props: { + onBar?: (data: number) => any; + foo: number; + } & import(\\"vue\\").VNodeProps & import(\\"vue\\").AllowedComponentProps & import(\\"vue\\").ComponentCustomProps; + expose(exposed: import(\\"vue\\").ShallowUnwrapRef<{ + baz: number; + }>): void; + attrs: any; + slots: Readonly<{ + default?(data: { + foo: number; + }): any; + }>; + emit: (e: 'bar', data: number) => void; + }; +}; +export default _default; +" +`; + exports[`vue-tsc-dts > Input: non-component/component.ts, Output: non-component/component.d.ts 1`] = ` "declare const _default: {}; export default _default; diff --git a/test-workspace/component-meta/generic/component.vue b/test-workspace/component-meta/generic/component.vue new file mode 100644 index 0000000000..39664c35ac --- /dev/null +++ b/test-workspace/component-meta/generic/component.vue @@ -0,0 +1,6 @@ + From 991cf5b5abcec69f29e5bdcd35e7ee73ff1026e4 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Wed, 6 Dec 2023 00:41:07 +0800 Subject: [PATCH 3/3] Update dts.spec.ts.snap --- packages/tsc/tests/__snapshots__/dts.spec.ts.snap | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/tsc/tests/__snapshots__/dts.spec.ts.snap b/packages/tsc/tests/__snapshots__/dts.spec.ts.snap index ba0ec4346d..2ffcb71db3 100644 --- a/packages/tsc/tests/__snapshots__/dts.spec.ts.snap +++ b/packages/tsc/tests/__snapshots__/dts.spec.ts.snap @@ -26,7 +26,7 @@ exports[`vue-tsc-dts > Input: generic/component.vue, Output: generic/component.v "declare const _default: (__VLS_props: { onBar?: (data: number) => any; foo: number; -} & import(\\"vue\\").VNodeProps & import(\\"vue\\").AllowedComponentProps & import(\\"vue\\").ComponentCustomProps, __VLS_ctx?: { +} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, __VLS_ctx?: { attrs: any; emit: (e: 'bar', data: number) => void; slots: Readonly<{ @@ -34,14 +34,14 @@ exports[`vue-tsc-dts > Input: generic/component.vue, Output: generic/component.v foo: number; }): any; }>; -}, __VLS_expose?: (exposed: import(\\"vue\\").ShallowUnwrapRef<{ +}, __VLS_expose?: (exposed: import("vue").ShallowUnwrapRef<{ baz: number; }>) => void, __VLS_setup?: Promise<{ props: { onBar?: (data: number) => any; foo: number; - } & import(\\"vue\\").VNodeProps & import(\\"vue\\").AllowedComponentProps & import(\\"vue\\").ComponentCustomProps; - expose(exposed: import(\\"vue\\").ShallowUnwrapRef<{ + } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps; + expose(exposed: import("vue").ShallowUnwrapRef<{ baz: number; }>): void; attrs: any; @@ -51,15 +51,15 @@ exports[`vue-tsc-dts > Input: generic/component.vue, Output: generic/component.v }): any; }>; emit: (e: 'bar', data: number) => void; -}>) => import(\\"vue\\").VNode) => import("vue").VNode & { __ctx?: { props: { onBar?: (data: number) => any; foo: number; - } & import(\\"vue\\").VNodeProps & import(\\"vue\\").AllowedComponentProps & import(\\"vue\\").ComponentCustomProps; - expose(exposed: import(\\"vue\\").ShallowUnwrapRef<{ + } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps; + expose(exposed: import("vue").ShallowUnwrapRef<{ baz: number; }>): void; attrs: any;