diff --git a/packages/language-core/lib/codegen/script/component.ts b/packages/language-core/lib/codegen/script/component.ts index c0a92e2997..970fb8031a 100644 --- a/packages/language-core/lib/codegen/script/component.ts +++ b/packages/language-core/lib/codegen/script/component.ts @@ -41,7 +41,7 @@ export function* generateComponent( yield generateSfcBlockSection(options.sfc.script, args.start + 1, args.end - 1, codeFeatures.all); } if (options.vueCompilerOptions.target >= 3.5 && scriptSetupRanges.templateRefs.length) { - yield `__typeRefs: {} as __VLS_Refs,${newLine}`; + yield `__typeRefs: {} as __VLS_TemplateResult['refs'],${newLine}`; } yield `})`; } @@ -142,7 +142,7 @@ export function* generatePropsOption( optionExpCodes.push(generateSfcBlockSection(scriptSetup, arg.start, arg.end, codeFeatures.navigation)); } if (inheritAttrs && options.templateCodegen?.inheritedAttrVars.size) { - let attrsType = `typeof __VLS_templateAttrs`; + let attrsType = `__VLS_TemplateResult['attrs']`; if (hasEmitsOption) { attrsType = `Omit<${attrsType}, \`on\${string}\`>`; } diff --git a/packages/language-core/lib/codegen/script/index.ts b/packages/language-core/lib/codegen/script/index.ts index 7702b673f6..6317feec8c 100644 --- a/packages/language-core/lib/codegen/script/index.ts +++ b/packages/language-core/lib/codegen/script/index.ts @@ -10,6 +10,7 @@ import { generateScriptSetup, generateScriptSetupImports } from './scriptSetup'; import { generateSrc } from './src'; import { generateTemplate } from './template'; import { generateGlobalTypes } from '../globalTypes'; +import { generateInternalComponent } from './internalComponent'; export const codeFeatures = { all: { @@ -112,7 +113,10 @@ export function* generateScript(options: ScriptCodegenOptions): Generator {`; - yield* generateTemplate(options, ctx, true); + const templateCodegenCtx = yield* generateTemplate(options, ctx, true); + if (templateCodegenCtx) { + yield* generateInternalComponent(options, ctx, templateCodegenCtx); + } yield `},${newLine}`; yield generateSfcBlockSection(options.sfc.script, classBlockEnd, options.sfc.script.content.length, codeFeatures.all); } @@ -135,7 +139,12 @@ export function* generateScript(options: ScriptCodegenOptions): Generator & __VLS_BuiltInPublicProps,${newLine}` + ` expose(exposed: import('${options.vueCompilerOptions.lib}').ShallowUnwrapRef<${scriptSetupRanges.expose.define ? 'typeof __VLS_exposed' : '{}'}>): void,${newLine}` + ` attrs: any,${newLine}` - + ` slots: __VLS_Slots,${newLine}` + + ` slots: __VLS_TemplateResult['slots'],${newLine}` + ` emit: ${emitTypes.length ? emitTypes.join(' & ') : `{}`},${newLine}` + ` }${endOfLine}`; yield ` })(),${newLine}`; // __VLS_setup = (async () => { @@ -246,9 +247,9 @@ function* generateSetupFunction( if (define?.arg) { setupCodeModifies.push([ [ - `<__VLS_Refs[`, + `<__VLS_TemplateResult['refs'][`, generateSfcBlockSection(scriptSetup, define.arg.start, define.arg.end, codeFeatures.navigation), - `], keyof __VLS_Refs>` + `], keyof __VLS_TemplateResult['refs']>` ], define.arg.start - 1, define.arg.start - 1 @@ -287,9 +288,13 @@ function* generateSetupFunction( yield* generateComponentProps(options, ctx, scriptSetup, scriptSetupRanges, definePropMirrors); yield* generateModelEmits(options, scriptSetup, scriptSetupRanges); yield* generateStyleModules(options, ctx); - yield* generateTemplate(options, ctx, false); - yield `type __VLS_Refs = typeof __VLS_templateRefs${endOfLine}`; - yield `type __VLS_Slots = typeof __VLS_templateSlots${endOfLine}`; + yield `function __VLS_template() {${newLine}`; + const templateCodegenCtx = yield* generateTemplate(options, ctx, false); + yield `}${endOfLine}`; + if (templateCodegenCtx) { + yield* generateInternalComponent(options, ctx, templateCodegenCtx); + } + yield `type __VLS_TemplateResult = ReturnType${endOfLine}`; if (syntax) { if (!options.vueCompilerOptions.skipTemplateCodegen && (options.templateCodegen?.hasSlot || scriptSetupRanges?.slots.define)) { @@ -297,7 +302,7 @@ function* generateSetupFunction( yield* generateComponent(options, ctx, scriptSetup, scriptSetupRanges); yield endOfLine; yield `${syntax} `; - yield `{} as ${ctx.localTypes.WithTemplateSlots}${endOfLine}`; + yield `{} as ${ctx.localTypes.WithTemplateSlots}${endOfLine}`; } else { yield `${syntax} `; diff --git a/packages/language-core/lib/codegen/script/template.ts b/packages/language-core/lib/codegen/script/template.ts index b2cc7d1f73..8abc6bce8e 100644 --- a/packages/language-core/lib/codegen/script/template.ts +++ b/packages/language-core/lib/codegen/script/template.ts @@ -7,7 +7,6 @@ import { forEachInterpolationSegment } from '../template/interpolation'; import { generateStyleScopedClasses } from '../template/styleScopedClasses'; import type { ScriptCodegenContext } from './context'; import { codeFeatures, type ScriptCodegenOptions } from './index'; -import { generateInternalComponent } from './internalComponent'; export function* generateTemplateCtx( options: ScriptCodegenOptions, @@ -93,7 +92,7 @@ export function* generateTemplate( options: ScriptCodegenOptions, ctx: ScriptCodegenContext, isClassComponent: boolean -): Generator { +): Generator { ctx.generatedTemplate = true; if (!options.vueCompilerOptions.skipTemplateCodegen) { @@ -104,15 +103,17 @@ export function* generateTemplate( yield* generateTemplateCtx(options, isClassComponent); yield* generateTemplateComponents(options); yield* generateTemplateBody(options, templateCodegenCtx); - yield* generateInternalComponent(options, ctx, templateCodegenCtx); + return templateCodegenCtx; } else { const templateUsageVars = [...getTemplateUsageVars(options, ctx)]; yield `// @ts-ignore${newLine}`; yield `[${templateUsageVars.join(', ')}]${newLine}`; - yield `const __VLS_templateSlots = {}${endOfLine}`; - yield `const __VLS_templateRefs = {}${endOfLine}`; - yield `const __VLS_templateAttrs = {}${endOfLine}`; + yield `return {${newLine}`; + yield ` slots: {},${newLine}`; + yield ` refs: {},${newLine}`; + yield ` attrs: {},${newLine}`; + yield `}${endOfLine}`; } } @@ -164,9 +165,11 @@ function* generateTemplateBody( } } - yield `const __VLS_templateSlots = ${options.scriptSetupRanges?.slots.name ?? '__VLS_slots'}${endOfLine}`; - yield `const __VLS_templateRefs = $refs${endOfLine}`; - yield `const __VLS_templateAttrs = {} as Partial${endOfLine}`; + yield `return {${newLine}`; + yield ` slots: ${options.scriptSetupRanges?.slots.name ?? '__VLS_slots'},${newLine}`; + yield ` refs: $refs,${newLine}`; + yield ` attrs: {} as Partial,${newLine}`; + yield `}${endOfLine}`; } export function* generateCssClassProperty( diff --git a/packages/language-core/lib/codegen/template/index.ts b/packages/language-core/lib/codegen/template/index.ts index 1665caecf5..5ebebbd297 100644 --- a/packages/language-core/lib/codegen/template/index.ts +++ b/packages/language-core/lib/codegen/template/index.ts @@ -68,7 +68,7 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator { diff --git a/packages/tsc/tests/__snapshots__/dts.spec.ts.snap b/packages/tsc/tests/__snapshots__/dts.spec.ts.snap index d53c99917d..7facce8132 100644 --- a/packages/tsc/tests/__snapshots__/dts.spec.ts.snap +++ b/packages/tsc/tests/__snapshots__/dts.spec.ts.snap @@ -633,26 +633,26 @@ export {}; `; exports[`vue-tsc-dts > Input: template-slots/component.vue, Output: template-slots/component.vue.d.ts 1`] = ` -"declare var __VLS_0: {}; -declare var __VLS_1: { - num: number; -}; -declare var __VLS_2: { - str: string; -}; -declare var __VLS_3: { - num: number; - str: string; -}; -declare const __VLS_templateSlots: { - "no-bind"?(_: typeof __VLS_0): any; - default?(_: typeof __VLS_1): any; - "named-slot"?(_: typeof __VLS_2): any; - vbind?(_: typeof __VLS_3): any; +"declare function __VLS_template(): { + slots: { + "no-bind"?(_: {}): any; + default?(_: { + num: number; + }): any; + "named-slot"?(_: { + str: string; + }): any; + vbind?(_: { + num: number; + str: string; + }): any; + }; + refs: {}; + attrs: Partial<{}>; }; -type __VLS_Slots = typeof __VLS_templateSlots; +type __VLS_TemplateResult = ReturnType; declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly>, {}, {}>; -declare const _default: __VLS_WithTemplateSlots; +declare const _default: __VLS_WithTemplateSlots; export default _default; type __VLS_WithTemplateSlots = T & { new (): { @@ -664,34 +664,38 @@ 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 const __VLS_templateSlots: Readonly<{ - default: (props: { - num: number; - }) => VNode[]; - 'named-slot': (props: { - str: string; - }) => VNode[]; - vbind: (props: { - num: number; - str: string; - }) => VNode[]; - 'no-bind': () => VNode[]; -}> & { - default: (props: { - num: number; - }) => VNode[]; - 'named-slot': (props: { - str: string; - }) => VNode[]; - vbind: (props: { - num: number; - str: string; - }) => VNode[]; - 'no-bind': () => VNode[]; +declare function __VLS_template(): { + slots: Readonly<{ + default: (props: { + num: number; + }) => VNode[]; + 'named-slot': (props: { + str: string; + }) => VNode[]; + vbind: (props: { + num: number; + str: string; + }) => VNode[]; + 'no-bind': () => VNode[]; + }> & { + default: (props: { + num: number; + }) => VNode[]; + 'named-slot': (props: { + str: string; + }) => VNode[]; + vbind: (props: { + num: number; + str: string; + }) => VNode[]; + 'no-bind': () => VNode[]; + }; + refs: {}; + attrs: Partial<{}>; }; -type __VLS_Slots = typeof __VLS_templateSlots; +type __VLS_TemplateResult = ReturnType; declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly>, {}, {}>; -declare const _default: __VLS_WithTemplateSlots; +declare const _default: __VLS_WithTemplateSlots; export default _default; type __VLS_WithTemplateSlots = T & { new (): { @@ -702,18 +706,22 @@ type __VLS_WithTemplateSlots = T & { `; exports[`vue-tsc-dts > Input: template-slots/component-destructuring.vue, Output: template-slots/component-destructuring.vue.d.ts 1`] = ` -"declare const __VLS_templateSlots: Readonly<{ - bottom: (props: { - num: number; - }) => any[]; -}> & { - bottom: (props: { - num: number; - }) => any[]; +"declare function __VLS_template(): { + slots: Readonly<{ + bottom: (props: { + num: number; + }) => any[]; + }> & { + bottom: (props: { + num: number; + }) => any[]; + }; + refs: {}; + attrs: Partial<{}>; }; -type __VLS_Slots = typeof __VLS_templateSlots; +type __VLS_TemplateResult = ReturnType; declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly>, {}, {}>; -declare const _default: __VLS_WithTemplateSlots; +declare const _default: __VLS_WithTemplateSlots; export default _default; type __VLS_WithTemplateSlots = T & { new (): { @@ -724,26 +732,26 @@ type __VLS_WithTemplateSlots = T & { `; exports[`vue-tsc-dts > Input: template-slots/component-no-script.vue, Output: template-slots/component-no-script.vue.d.ts 1`] = ` -"declare var __VLS_0: {}; -declare var __VLS_1: { - num: number; -}; -declare var __VLS_2: { - str: string; -}; -declare var __VLS_3: { - num: number; - str: string; -}; -declare const __VLS_templateSlots: { - "no-bind"?(_: typeof __VLS_0): any; - default?(_: typeof __VLS_1): any; - "named-slot"?(_: typeof __VLS_2): any; - vbind?(_: typeof __VLS_3): any; +"declare function __VLS_template(): { + slots: { + "no-bind"?(_: {}): any; + default?(_: { + num: number; + }): any; + "named-slot"?(_: { + str: string; + }): any; + vbind?(_: { + num: number; + str: string; + }): any; + }; + refs: {}; + attrs: Partial<{}>; }; -type __VLS_Slots = typeof __VLS_templateSlots; +type __VLS_TemplateResult = ReturnType; declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly>, {}, {}>; -declare const _default: __VLS_WithTemplateSlots; +declare const _default: __VLS_WithTemplateSlots; export default _default; type __VLS_WithTemplateSlots = T & { new (): {