From b077859445aae0db9dc81c6c0047f9e56adeae6b Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Fri, 30 Aug 2024 19:17:05 +0800 Subject: [PATCH 1/6] fix(language-core): isolate $refs type --- .../language-core/lib/codegen/globalTypes.ts | 7 ++++ .../language-core/lib/codegen/localTypes.ts | 15 --------- .../lib/codegen/script/internalComponent.ts | 3 -- .../lib/codegen/script/template.ts | 32 +++++++++++++------ .../lib/codegen/template/index.ts | 8 ++--- .../tsc/tests/__snapshots__/dts.spec.ts.snap | 32 +++---------------- packages/tsc/tests/typecheck.spec.ts | 4 +-- .../vue3.5/templateRef_missingImport/main.vue | 8 +++++ 8 files changed, 48 insertions(+), 61 deletions(-) create mode 100644 test-workspace/tsc/passedFixtures/vue3.5/templateRef_missingImport/main.vue diff --git a/packages/language-core/lib/codegen/globalTypes.ts b/packages/language-core/lib/codegen/globalTypes.ts index 19689701d5..285b510600 100644 --- a/packages/language-core/lib/codegen/globalTypes.ts +++ b/packages/language-core/lib/codegen/globalTypes.ts @@ -69,6 +69,13 @@ type __VLS_NormalizeEmits = __VLS_PrettifyGlobal< > >; type __VLS_PrettifyGlobal = { [K in keyof T]: T[K]; } & {}; +type __VLS_PickRefsExpose = T extends object + ? { [K in keyof T]: (T[K] extends any[] + ? Parameters[0][] + : T[K] extends { expose?: (exposed: infer E) => void } + ? E + : T[K]) | null } + : never; declare function __VLS_getVForSourceType(source: number): [number, number, number][]; declare function __VLS_getVForSourceType(source: string): [string, number, number][]; diff --git a/packages/language-core/lib/codegen/localTypes.ts b/packages/language-core/lib/codegen/localTypes.ts index e244f16f0f..d4939c3bf6 100644 --- a/packages/language-core/lib/codegen/localTypes.ts +++ b/packages/language-core/lib/codegen/localTypes.ts @@ -80,19 +80,6 @@ type __VLS_TypePropsToOption = { `__VLS_OmitIndexSignature`, () => `type __VLS_OmitIndexSignature = { [K in keyof T as {} extends Record ? never : K]: T[K]; }${endOfLine}` ); - const PickRefsExpose = defineHelper( - `__VLS_PickRefsExpose`, - () => ` -type __VLS_PickRefsExpose = T extends object - ? { [K in keyof T]: (T[K] extends any[] - ? Parameters[0][] - : T[K] extends { expose?: (exposed: infer E) => void } - ? E - : T[K]) | null } - : never; -`.trimStart() - ); - const helpers = { [PrettifyLocal.name]: PrettifyLocal, [OmitKeepDiscriminatedUnion.name]: OmitKeepDiscriminatedUnion, @@ -101,7 +88,6 @@ type __VLS_PickRefsExpose = T extends object [PropsChildren.name]: PropsChildren, [TypePropsToOption.name]: TypePropsToOption, [OmitIndexSignature.name]: OmitIndexSignature, - [PickRefsExpose.name]: PickRefsExpose, }; used.clear(); @@ -117,7 +103,6 @@ type __VLS_PickRefsExpose = T extends object get PropsChildren() { return PropsChildren.name; }, get TypePropsToOption() { return TypePropsToOption.name; }, get OmitIndexSignature() { return OmitIndexSignature.name; }, - get PickRefsExpose() { return PickRefsExpose.name; }, }; function* generate(names: string[]) { diff --git a/packages/language-core/lib/codegen/script/internalComponent.ts b/packages/language-core/lib/codegen/script/internalComponent.ts index 137a15997a..bfa36b65a8 100644 --- a/packages/language-core/lib/codegen/script/internalComponent.ts +++ b/packages/language-core/lib/codegen/script/internalComponent.ts @@ -47,9 +47,6 @@ export function* generateInternalComponent( } yield `}${endOfLine}`; // return { yield `},${newLine}`; // setup() { - if (options.vueCompilerOptions.target >= 3.5) { - yield `__typeRefs: {} as __VLS_Refs,${newLine}`; - } if (options.sfc.scriptSetup && options.scriptSetupRanges && !ctx.bypassDefineComponent) { const emitOptionCodes = [...generateEmitsOption(options, options.sfc.scriptSetup, options.scriptSetupRanges)]; for (const code of emitOptionCodes) { diff --git a/packages/language-core/lib/codegen/script/template.ts b/packages/language-core/lib/codegen/script/template.ts index 695d0ace06..ac41fb26aa 100644 --- a/packages/language-core/lib/codegen/script/template.ts +++ b/packages/language-core/lib/codegen/script/template.ts @@ -13,20 +13,35 @@ export function* generateTemplateCtx( options: ScriptCodegenOptions, isClassComponent: boolean ): Generator { - const types = []; + const exps = []; if (isClassComponent) { - types.push(`typeof this`); + exps.push(`this`); } else { - types.push(`InstanceType<__VLS_PickNotAny {}>>`); + exps.push(`{} as InstanceType<__VLS_PickNotAny {}>>`); } if (options.vueCompilerOptions.petiteVueExtensions.some(ext => options.fileBaseName.endsWith(ext))) { - types.push(`typeof globalThis`); + exps.push(`globalThis`); } if (options.sfc.styles.some(style => style.module)) { - types.push(`__VLS_StyleModules`); + exps.push(`{} as __VLS_StyleModules`); + } + exps.push(`{ $refs: __VLS_refs }`); + + yield `const __VLS_ctx = `; + if (exps.length === 1) { + yield exps[0]; + yield endOfLine; + } + else { + yield `{${newLine}`; + for (const exp of exps) { + yield `...`; + yield exp; + yield `,${newLine}`; + } + yield `}${endOfLine}`; } - yield `let __VLS_ctx!: ${types.join(' & ')}${endOfLine}`; } export function* generateTemplateComponents(options: ScriptCodegenOptions): Generator { @@ -87,7 +102,7 @@ export function* generateTemplate( }); yield* generateTemplateCtx(options, isClassComponent); yield* generateTemplateComponents(options); - yield* generateTemplateBody(options, ctx, templateCodegenCtx); + yield* generateTemplateBody(options, templateCodegenCtx); yield* generateInternalComponent(options, ctx, templateCodegenCtx); } else { @@ -100,7 +115,6 @@ export function* generateTemplate( function* generateTemplateBody( options: ScriptCodegenOptions, - ctx: ScriptCodegenContext, templateCodegenCtx: TemplateCodegenContext ): Generator { const firstClasses = new Set(); @@ -149,7 +163,7 @@ function* generateTemplateBody( yield `const __VLS_templateResult = {`; yield `slots: ${options.scriptSetupRanges?.slots.name ?? '__VLS_slots'},${newLine}`; - yield `refs: __VLS_refs as ${ctx.localTypes.PickRefsExpose},${newLine}`; + yield `refs: __VLS_refs,${newLine}`; yield `attrs: {} as Partial,${newLine}`; yield `}${endOfLine}`; } diff --git a/packages/language-core/lib/codegen/template/index.ts b/packages/language-core/lib/codegen/template/index.ts index c68a820da3..ebff979bca 100644 --- a/packages/language-core/lib/codegen/template/index.ts +++ b/packages/language-core/lib/codegen/template/index.ts @@ -51,7 +51,7 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator,${newLine}`; } - yield `}${endOfLine}`; + yield `}>${endOfLine}`; } function* generateSlotsType(): Generator { diff --git a/packages/tsc/tests/__snapshots__/dts.spec.ts.snap b/packages/tsc/tests/__snapshots__/dts.spec.ts.snap index a134e8d034..0b12b2b53a 100644 --- a/packages/tsc/tests/__snapshots__/dts.spec.ts.snap +++ b/packages/tsc/tests/__snapshots__/dts.spec.ts.snap @@ -645,7 +645,6 @@ declare var __VLS_3: { str: string; }; declare var __VLS_inheritedAttrs: {}; -declare const __VLS_refs: {}; declare const __VLS_templateResult: { slots: { "no-bind"?(_: typeof __VLS_0): any; @@ -653,18 +652,13 @@ declare const __VLS_templateResult: { "named-slot"?(_: typeof __VLS_2): any; vbind?(_: typeof __VLS_3): any; }; - refs: __VLS_PickRefsExpose; + refs: {}; attrs: Partial; }; type __VLS_Slots = typeof __VLS_templateResult['slots']; declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly>, {}, {}>; declare const _default: __VLS_WithTemplateSlots; export default _default; -type __VLS_PickRefsExpose = T extends object ? { - [K in keyof T]: (T[K] extends any[] ? Parameters[0][] : T[K] extends { - expose?: (exposed: infer E) => void; - } ? E : T[K]) | null; -} : never; type __VLS_WithTemplateSlots = T & { new (): { $slots: S; @@ -676,7 +670,6 @@ type __VLS_WithTemplateSlots = 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 var __VLS_inheritedAttrs: {}; -declare const __VLS_refs: {}; declare const __VLS_templateResult: { slots: Readonly<{ default: (props: { @@ -703,18 +696,13 @@ declare const __VLS_templateResult: { }) => VNode[]; 'no-bind': () => VNode[]; }; - refs: __VLS_PickRefsExpose; + refs: {}; attrs: Partial; }; type __VLS_Slots = typeof __VLS_templateResult['slots']; declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly>, {}, {}>; declare const _default: __VLS_WithTemplateSlots; export default _default; -type __VLS_PickRefsExpose = T extends object ? { - [K in keyof T]: (T[K] extends any[] ? Parameters[0][] : T[K] extends { - expose?: (exposed: infer E) => void; - } ? E : T[K]) | null; -} : never; type __VLS_WithTemplateSlots = T & { new (): { $slots: S; @@ -725,7 +713,6 @@ type __VLS_WithTemplateSlots = T & { exports[`vue-tsc-dts > Input: template-slots/component-destructuring.vue, Output: template-slots/component-destructuring.vue.d.ts 1`] = ` "declare var __VLS_inheritedAttrs: {}; -declare const __VLS_refs: {}; declare const __VLS_templateResult: { slots: Readonly<{ bottom: (props: { @@ -736,18 +723,13 @@ declare const __VLS_templateResult: { num: number; }) => any[]; }; - refs: __VLS_PickRefsExpose; + refs: {}; attrs: Partial; }; type __VLS_Slots = typeof __VLS_templateResult['slots']; declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly>, {}, {}>; declare const _default: __VLS_WithTemplateSlots; export default _default; -type __VLS_PickRefsExpose = T extends object ? { - [K in keyof T]: (T[K] extends any[] ? Parameters[0][] : T[K] extends { - expose?: (exposed: infer E) => void; - } ? E : T[K]) | null; -} : never; type __VLS_WithTemplateSlots = T & { new (): { $slots: S; @@ -769,7 +751,6 @@ declare var __VLS_3: { str: string; }; declare var __VLS_inheritedAttrs: {}; -declare const __VLS_refs: {}; declare const __VLS_templateResult: { slots: { "no-bind"?(_: typeof __VLS_0): any; @@ -777,18 +758,13 @@ declare const __VLS_templateResult: { "named-slot"?(_: typeof __VLS_2): any; vbind?(_: typeof __VLS_3): any; }; - refs: __VLS_PickRefsExpose; + refs: {}; attrs: Partial; }; type __VLS_Slots = typeof __VLS_templateResult['slots']; declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly>, {}, {}>; declare const _default: __VLS_WithTemplateSlots; export default _default; -type __VLS_PickRefsExpose = T extends object ? { - [K in keyof T]: (T[K] extends any[] ? Parameters[0][] : T[K] extends { - expose?: (exposed: infer E) => void; - } ? E : T[K]) | null; -} : never; type __VLS_WithTemplateSlots = T & { new (): { $slots: S; diff --git a/packages/tsc/tests/typecheck.spec.ts b/packages/tsc/tests/typecheck.spec.ts index a7cc585449..905ddec632 100644 --- a/packages/tsc/tests/typecheck.spec.ts +++ b/packages/tsc/tests/typecheck.spec.ts @@ -9,8 +9,8 @@ describe(`vue-tsc`, () => { getTscOutput('stable') ).toMatchInlineSnapshot(` [ - "test-workspace/tsc/failureFixtures/directives/main.vue(4,6): error TS2339: Property 'notExist' does not exist on type 'CreateComponentPublicInstance>, { exist: typeof exist; }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 12 more ..., {}>'.", - "test-workspace/tsc/failureFixtures/directives/main.vue(9,6): error TS2339: Property 'notExist' does not exist on type 'CreateComponentPublicInstance>, { exist: typeof exist; }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 12 more ..., {}>'.", + "test-workspace/tsc/failureFixtures/directives/main.vue(4,6): error TS2339: Property 'notExist' does not exist on type '{ $refs: {}; $: ComponentInternalInstance; $data: {}; $props: Partial<{}> & Omit<{} & VNodeProps & AllowedComponentProps & ComponentCustomProps & Readonly<...>, never>; ... 10 more ...; exist: typeof exist; }'.", + "test-workspace/tsc/failureFixtures/directives/main.vue(9,6): error TS2339: Property 'notExist' does not exist on type '{ $refs: {}; $: ComponentInternalInstance; $data: {}; $props: Partial<{}> & Omit<{} & VNodeProps & AllowedComponentProps & ComponentCustomProps & Readonly<...>, never>; ... 10 more ...; exist: typeof exist; }'.", "test-workspace/tsc/failureFixtures/directives/main.vue(12,2): error TS2578: Unused '@ts-expect-error' directive.", ] `); diff --git a/test-workspace/tsc/passedFixtures/vue3.5/templateRef_missingImport/main.vue b/test-workspace/tsc/passedFixtures/vue3.5/templateRef_missingImport/main.vue new file mode 100644 index 0000000000..24f56a4a07 --- /dev/null +++ b/test-workspace/tsc/passedFixtures/vue3.5/templateRef_missingImport/main.vue @@ -0,0 +1,8 @@ + + + From 75ab7fcc59ee24c9956b2599b06b49464139be86 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Fri, 30 Aug 2024 19:21:25 +0800 Subject: [PATCH 2/6] Update typecheck.spec.ts --- packages/tsc/tests/typecheck.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/tsc/tests/typecheck.spec.ts b/packages/tsc/tests/typecheck.spec.ts index 905ddec632..fae766986a 100644 --- a/packages/tsc/tests/typecheck.spec.ts +++ b/packages/tsc/tests/typecheck.spec.ts @@ -21,8 +21,8 @@ describe(`vue-tsc`, () => { getTscOutput('next') ).toMatchInlineSnapshot(` [ - "test-workspace/tsc/failureFixtures/directives/main.vue(4,6): error TS2339: Property 'notExist' does not exist on type 'CreateComponentPublicInstance>, { exist: typeof exist; }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 12 more ..., {}>'.", - "test-workspace/tsc/failureFixtures/directives/main.vue(9,6): error TS2339: Property 'notExist' does not exist on type 'CreateComponentPublicInstance>, { exist: typeof exist; }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 12 more ..., {}>'.", + "test-workspace/tsc/failureFixtures/directives/main.vue(4,6): error TS2339: Property 'notExist' does not exist on type '{ $refs: {}; $: ComponentInternalInstance; $data: {}; $props: Partial<{}> & Omit<{} & VNodeProps & AllowedComponentProps & ComponentCustomProps & Readonly<...>, never>; ... 10 more ...; exist: typeof exist; }'.", + "test-workspace/tsc/failureFixtures/directives/main.vue(9,6): error TS2339: Property 'notExist' does not exist on type '{ $refs: {}; $: ComponentInternalInstance; $data: {}; $props: Partial<{}> & Omit<{} & VNodeProps & AllowedComponentProps & ComponentCustomProps & Readonly<...>, never>; ... 10 more ...; exist: typeof exist; }'.", "test-workspace/tsc/failureFixtures/directives/main.vue(12,2): error TS2578: Unused '@ts-expect-error' directive.", "test-workspace/tsc/passedFixtures/#3373/tsconfig.json(4,3): error TS5102: Option 'importsNotUsedAsValues' has been removed. Please remove it from your configuration. Use 'verbatimModuleSyntax' instead.", From f9ece309b767847a93a83ca8dcacda946188aa86 Mon Sep 17 00:00:00 2001 From: zhiyuanzmj <260480378@qq.com> Date: Fri, 30 Aug 2024 21:17:39 +0800 Subject: [PATCH 3/6] chore: up test --- .../tsc/passedFixtures/vue3.5/templateRef/components.d.ts | 5 +++++ .../tsc/passedFixtures/vue3.5/templateRef/template-ref.vue | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 test-workspace/tsc/passedFixtures/vue3.5/templateRef/components.d.ts diff --git a/test-workspace/tsc/passedFixtures/vue3.5/templateRef/components.d.ts b/test-workspace/tsc/passedFixtures/vue3.5/templateRef/components.d.ts new file mode 100644 index 0000000000..8cc40dc371 --- /dev/null +++ b/test-workspace/tsc/passedFixtures/vue3.5/templateRef/components.d.ts @@ -0,0 +1,5 @@ +declare module 'vue' { + export interface GlobalComponents { + Generic: typeof import('./generic.vue')['default']; + } +} diff --git a/test-workspace/tsc/passedFixtures/vue3.5/templateRef/template-ref.vue b/test-workspace/tsc/passedFixtures/vue3.5/templateRef/template-ref.vue index 2a08b3ce79..c490ca6c56 100644 --- a/test-workspace/tsc/passedFixtures/vue3.5/templateRef/template-ref.vue +++ b/test-workspace/tsc/passedFixtures/vue3.5/templateRef/template-ref.vue @@ -1,10 +1,8 @@