diff --git a/packages/language-core/lib/codegen/script/template.ts b/packages/language-core/lib/codegen/script/template.ts index 7c5d85d6ec..851a18c1b1 100644 --- a/packages/language-core/lib/codegen/script/template.ts +++ b/packages/language-core/lib/codegen/script/template.ts @@ -13,28 +13,55 @@ export function* generateTemplateCtx( options: ScriptCodegenOptions, isClassComponent: boolean ): Generator { - const exps = []; + const baseExps = []; + const extraExps = []; + if (isClassComponent) { - exps.push(`this`); + baseExps.push(`this`); } else { - exps.push(`{} as InstanceType<__VLS_PickNotAny {}>>`); + baseExps.push(`{} as InstanceType<__VLS_PickNotAny {}>>`); } if (options.vueCompilerOptions.petiteVueExtensions.some(ext => options.fileBaseName.endsWith(ext))) { - exps.push(`globalThis`); + extraExps.push(`globalThis`); } if (options.sfc.styles.some(style => style.module)) { - exps.push(`{} as __VLS_StyleModules`); + extraExps.push(`{} as __VLS_StyleModules`); + } + if (options.scriptSetupRanges?.templateRefs.length) { + let exp = `{} as import('${options.vueCompilerOptions.lib}').UnwrapRef<{${newLine}`; + for (const { name } of options.scriptSetupRanges.templateRefs) { + if (name) { + exp += `${name}: typeof ${name}${newLine}`; + } + } + exp += `}>${newLine}`; + extraExps.push(exp); } - yield `const __VLS_ctx = `; - if (exps.length === 1) { - yield exps[0]; + yield `const __VLS_ctxBase = `; + if (baseExps.length === 1) { + yield baseExps[0]; yield endOfLine; } else { yield `{${newLine}`; - for (const exp of exps) { + for (const exp of baseExps) { + yield `...`; + yield exp; + yield `,${newLine}`; + } + yield `}${endOfLine}`; + } + + yield `const __VLS_ctx = `; + if (extraExps.length === 0) { + yield `__VLS_ctxBase${endOfLine}`; + } + else { + yield `{${newLine}`; + yield `...__VLS_ctxBase,${newLine}`; + for (const exp of extraExps) { yield `...`; yield exp; yield `,${newLine}`; @@ -76,7 +103,7 @@ export function* generateTemplateComponents(options: ScriptCodegenOptions): Gene exps.push(`{} as NonNullable`); exps.push(`{} as __VLS_GlobalComponents`); - exps.push(`{} as typeof __VLS_ctx`); + exps.push(`__VLS_ctxBase`); yield `const __VLS_components = {${newLine}`; for (const type of exps) { diff --git a/packages/language-core/lib/codegen/template/element.ts b/packages/language-core/lib/codegen/template/element.ts index 7bae0f2b32..b8243293de 100644 --- a/packages/language-core/lib/codegen/template/element.ts +++ b/packages/language-core/lib/codegen/template/element.ts @@ -229,15 +229,14 @@ export function* generateComponent( options.templateRefNames.set(refName, [varName, offset!]); ctx.usedComponentCtxVars.add(var_defineComponentCtx); - yield `// @ts-ignore${newLine}`; + yield `var ${varName} = {} as (Parameters[0] | null)`; if (node.codegenNode?.type === CompilerDOM.NodeTypes.VNODE_CALL && node.codegenNode.props?.type === CompilerDOM.NodeTypes.JS_OBJECT_EXPRESSION - && node.codegenNode.props.properties.find(({ key }) => key.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION && key.content === 'ref_for') + && node.codegenNode.props.properties.some(({ key }) => key.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION && key.content === 'ref_for') ) { - yield `var ${varName} = [{} as Parameters[0]]${endOfLine}`; - } else { - yield `var ${varName} = {} as Parameters[0]${endOfLine}`; + yield `[]`; } + yield `${endOfLine}`; } const usedComponentEventsVar = yield* generateElementEvents(options, ctx, node, var_functionalComponent, var_componentInstance, var_componentEmit, var_componentEvents); diff --git a/packages/language-core/lib/codegen/template/index.ts b/packages/language-core/lib/codegen/template/index.ts index 7b49c45017..96ce84035b 100644 --- a/packages/language-core/lib/codegen/template/index.ts +++ b/packages/language-core/lib/codegen/template/index.ts @@ -65,7 +65,7 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator - {{ exactType($refs.templateRef.$refs.generic.foo, {} as 1) }} + {{ exactType($refs.templateRef?.$refs.generic?.foo, {} as (1 | undefined)) }} 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 6547d70c37..f9a9bfee32 100644 --- a/test-workspace/tsc/passedFixtures/vue3.5/templateRef/template-ref.vue +++ b/test-workspace/tsc/passedFixtures/vue3.5/templateRef/template-ref.vue @@ -4,7 +4,7 @@ import { exactType } from '../../shared'; const comp1 = useTemplateRef('generic'); if (comp1.value) { - exactType(comp1.value.foo, 1) + exactType(comp1.value.foo, 1); } const comp2 = useTemplateRef('v-for'); @@ -20,8 +20,11 @@ if (comp3.value) {