diff --git a/packages/language-core/lib/codegen/script/index.ts b/packages/language-core/lib/codegen/script/index.ts index d805ec1ef3..9c975f325d 100644 --- a/packages/language-core/lib/codegen/script/index.ts +++ b/packages/language-core/lib/codegen/script/index.ts @@ -84,7 +84,6 @@ export function* generateScript(options: ScriptCodegenOptions): Generator -): Generator { - const definePropProposalA = scriptSetup.content.trimStart().startsWith('// @experimentalDefinePropProposal=kevinEdition') || options.vueCompilerOptions.experimentalDefinePropProposal === 'kevinEdition'; - const definePropProposalB = scriptSetup.content.trimStart().startsWith('// @experimentalDefinePropProposal=johnsonEdition') || options.vueCompilerOptions.experimentalDefinePropProposal === 'johnsonEdition'; - - if (definePropProposalA || definePropProposalB) { - yield `type __VLS_PropOptions = Exclude, import('${options.vueCompilerOptions.lib}').PropType>${endOfLine}`; - if (definePropProposalA) { - yield `declare function defineProp(name: string, options: ({ required: true } | { default: T }) & __VLS_PropOptions): import('${options.vueCompilerOptions.lib}').ComputedRef${endOfLine}`; - yield `declare function defineProp(name?: string, options?: __VLS_PropOptions): import('${options.vueCompilerOptions.lib}').ComputedRef${endOfLine}`; - } - if (definePropProposalB) { - yield `declare function defineProp(value: T | (() => T), required?: boolean, options?: __VLS_PropOptions): import('${options.vueCompilerOptions.lib}').ComputedRef${endOfLine}`; - yield `declare function defineProp(value: T | (() => T) | undefined, required: true, options?: __VLS_PropOptions): import('${options.vueCompilerOptions.lib}').ComputedRef${endOfLine}`; - yield `declare function defineProp(value?: T | (() => T), required?: boolean, options?: __VLS_PropOptions): import('${options.vueCompilerOptions.lib}').ComputedRef${endOfLine}`; - } - } -} diff --git a/packages/language-core/lib/codegen/script/scriptSetup.ts b/packages/language-core/lib/codegen/script/scriptSetup.ts index 5b7e0bceea..bb6ad08d80 100644 --- a/packages/language-core/lib/codegen/script/scriptSetup.ts +++ b/packages/language-core/lib/codegen/script/scriptSetup.ts @@ -17,7 +17,6 @@ export function* generateScriptSetupImports( 0, codeFeatures.all, ]; - yield newLine; } export function* generateScriptSetup( @@ -96,16 +95,6 @@ function* generateSetupFunction( scriptSetupRanges: ScriptSetupRanges, syntax: 'return' | 'export default' | undefined ): Generator { - if (options.vueCompilerOptions.target >= 3.3) { - yield `const { `; - for (const macro of Object.keys(options.vueCompilerOptions.macros)) { - if (!ctx.bindingNames.has(macro) && macro !== 'templateRef') { - yield macro + `, `; - } - } - yield `} = await import('${options.vueCompilerOptions.lib}')${endOfLine}`; - } - ctx.scriptSetupGeneratedOffset = options.getGeneratedLength() - scriptSetupRanges.importSectionEndOffset; let setupCodeModifies: [Code[], number, number][] = []; @@ -280,6 +269,8 @@ function* generateSetupFunction( yield generateSfcBlockSection(scriptSetup, nextStart, scriptSetup.content.length, codeFeatures.all); yield* generateScriptSectionPartiallyEnding(scriptSetup.name, scriptSetup.content.length, '#3632/scriptSetup.vue'); + yield* generateMacros(options, ctx); + yield* generateDefineProp(options, scriptSetup); if (scriptSetupRanges.defineProps?.typeArg && scriptSetupRanges.withDefaults?.arg) { // fix https://github.com/vuejs/language-tools/issues/1187 @@ -317,6 +308,42 @@ function* generateSetupFunction( } } +function* generateMacros( + options: ScriptCodegenOptions, + ctx: ScriptCodegenContext +): Generator { + if (options.vueCompilerOptions.target >= 3.3) { + yield `declare const { `; + for (const macro of Object.keys(options.vueCompilerOptions.macros)) { + if (!ctx.bindingNames.has(macro)) { + yield `${macro}, `; + } + } + yield `}: typeof import('${options.vueCompilerOptions.lib}')${endOfLine}`; + } +} + +function* generateDefineProp( + options: ScriptCodegenOptions, + scriptSetup: NonNullable +): Generator { + const definePropProposalA = scriptSetup.content.trimStart().startsWith('// @experimentalDefinePropProposal=kevinEdition') || options.vueCompilerOptions.experimentalDefinePropProposal === 'kevinEdition'; + const definePropProposalB = scriptSetup.content.trimStart().startsWith('// @experimentalDefinePropProposal=johnsonEdition') || options.vueCompilerOptions.experimentalDefinePropProposal === 'johnsonEdition'; + + if (definePropProposalA || definePropProposalB) { + yield `type __VLS_PropOptions = Exclude, import('${options.vueCompilerOptions.lib}').PropType>${endOfLine}`; + if (definePropProposalA) { + yield `declare function defineProp(name: string, options: ({ required: true } | { default: T }) & __VLS_PropOptions): import('${options.vueCompilerOptions.lib}').ComputedRef${endOfLine}`; + yield `declare function defineProp(name?: string, options?: __VLS_PropOptions): import('${options.vueCompilerOptions.lib}').ComputedRef${endOfLine}`; + } + if (definePropProposalB) { + yield `declare function defineProp(value: T | (() => T), required?: boolean, options?: __VLS_PropOptions): import('${options.vueCompilerOptions.lib}').ComputedRef${endOfLine}`; + yield `declare function defineProp(value: T | (() => T) | undefined, required: true, options?: __VLS_PropOptions): import('${options.vueCompilerOptions.lib}').ComputedRef${endOfLine}`; + yield `declare function defineProp(value?: T | (() => T), required?: boolean, options?: __VLS_PropOptions): import('${options.vueCompilerOptions.lib}').ComputedRef${endOfLine}`; + } + } +} + function* generateDefineWithType( scriptSetup: NonNullable, statement: TextRange, diff --git a/packages/tsc/tests/typecheck.spec.ts b/packages/tsc/tests/typecheck.spec.ts index ac97fb2c35..9ca92a87df 100644 --- a/packages/tsc/tests/typecheck.spec.ts +++ b/packages/tsc/tests/typecheck.spec.ts @@ -13,6 +13,8 @@ describe(`vue-tsc`, () => { "test-workspace/tsc/failureFixtures/#3632/both.vue(7,1): error TS1109: Expression expected.", "test-workspace/tsc/failureFixtures/#3632/script.vue(3,1): error TS1109: Expression expected.", "test-workspace/tsc/failureFixtures/#3632/scriptSetup.vue(3,1): error TS1109: Expression expected.", + "test-workspace/tsc/failureFixtures/#5071/withoutScript.vue(2,26): error TS1005: ';' expected.", + "test-workspace/tsc/failureFixtures/#5071/withScript.vue(1,19): error TS1005: ';' expected.", "test-workspace/tsc/failureFixtures/directives/main.vue(4,6): error TS2339: Property 'notExist' does not exist on type 'CreateComponentPublicInstanceWithMixins, { exist: typeof exist; }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 18 more ..., {}>'.", "test-workspace/tsc/failureFixtures/directives/main.vue(9,6): error TS2339: Property 'notExist' does not exist on type 'CreateComponentPublicInstanceWithMixins, { exist: typeof exist; }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 18 more ..., {}>'.", "test-workspace/tsc/failureFixtures/directives/main.vue(12,2): error TS2578: Unused '@ts-expect-error' directive.", @@ -32,6 +34,8 @@ describe(`vue-tsc`, () => { "test-workspace/tsc/failureFixtures/#3632/both.vue(7,1): error TS1109: Expression expected.", "test-workspace/tsc/failureFixtures/#3632/script.vue(3,1): error TS1109: Expression expected.", "test-workspace/tsc/failureFixtures/#3632/scriptSetup.vue(3,1): error TS1109: Expression expected.", + "test-workspace/tsc/failureFixtures/#5071/withoutScript.vue(2,26): error TS1005: ';' expected.", + "test-workspace/tsc/failureFixtures/#5071/withScript.vue(1,19): error TS1005: ';' expected.", "test-workspace/tsc/failureFixtures/directives/main.vue(4,6): error TS2339: Property 'notExist' does not exist on type 'CreateComponentPublicInstanceWithMixins, { exist: typeof exist; }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 18 more ..., {}>'.", "test-workspace/tsc/failureFixtures/directives/main.vue(9,6): error TS2339: Property 'notExist' does not exist on type 'CreateComponentPublicInstanceWithMixins, { exist: typeof exist; }, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 18 more ..., {}>'.", "test-workspace/tsc/failureFixtures/directives/main.vue(12,2): error TS2578: Unused '@ts-expect-error' directive.", diff --git a/test-workspace/tsc/failureFixtures/#5071/tsconfig.json b/test-workspace/tsc/failureFixtures/#5071/tsconfig.json new file mode 100644 index 0000000000..52ecbeb3c3 --- /dev/null +++ b/test-workspace/tsc/failureFixtures/#5071/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../../tsconfig.base.json", + "include": [ "**/*" ] +} diff --git a/test-workspace/tsc/failureFixtures/#5071/withScript.vue b/test-workspace/tsc/failureFixtures/#5071/withScript.vue new file mode 100644 index 0000000000..f2acf4d1eb --- /dev/null +++ b/test-workspace/tsc/failureFixtures/#5071/withScript.vue @@ -0,0 +1,6 @@ + + + diff --git a/test-workspace/tsc/failureFixtures/#5071/withoutScript.vue b/test-workspace/tsc/failureFixtures/#5071/withoutScript.vue new file mode 100644 index 0000000000..0a5bb66ff8 --- /dev/null +++ b/test-workspace/tsc/failureFixtures/#5071/withoutScript.vue @@ -0,0 +1,3 @@ + diff --git a/test-workspace/tsc/tsconfig.json b/test-workspace/tsc/tsconfig.json index 219f289b2f..bee2125e24 100644 --- a/test-workspace/tsc/tsconfig.json +++ b/test-workspace/tsc/tsconfig.json @@ -3,6 +3,7 @@ "references": [ { "path": "./failureFixtures/#3632" }, // { "path": "./failureFixtures/#4569" }, // TODO: not working with --build flag + { "path": "./failureFixtures/#5071" }, { "path": "./failureFixtures/directives" }, { "path": "./passedFixtures/#1886" },