From f01266693a577a6be8ce560393a332f5e507cbd2 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Wed, 19 Mar 2025 12:27:32 +0100 Subject: [PATCH] fix: ensure exports in runes mode are marked as used Ensure they are read as part of exporting the types #2717 --- .../src/svelte2tsx/nodes/ExportedNames.ts | 31 ++++++++++--------- .../ts-export-list-runes.v5/expectedv2.ts | 2 +- .../expectedv2.ts | 2 +- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts b/packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts index eee94a784..2703f6a80 100644 --- a/packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts +++ b/packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts @@ -758,18 +758,17 @@ export class ExportedNames { let str = ''; if (others.length > 0 || this.usesRunes() || needsAccessors) { + const exports = needsAccessors ? names : others; + if (others.length > 0 || needsAccessors) { if (this.isTsFile) { str += - ', exports: {} as any as { ' + - this.createReturnElementsType( - needsAccessors ? names : others, - undefined, - true - ).join(',') + + // Reference imports that have a type, else they are marked as unused if nothing in the component references them + `, exports: {${this.createReturnElements(this.usesRunes() ? others : [], false, true)}} as any as { ` + + this.createReturnElementsType(exports, undefined, true).join(',') + ' }'; } else { - str += `, exports: /** @type {{${this.createReturnElementsType(needsAccessors ? names : others, false, true)}}} */ ({})`; + str += `, exports: /** @type {{${this.createReturnElementsType(exports, false, true)}}} */ ({})`; } } else { // Always add that, in TS5.5+ the type for Exports is infered to never when this is not present, which breaks types. @@ -791,14 +790,18 @@ export class ExportedNames { private createReturnElements( names: Array<[string, ExportedName]>, - dontAddTypeDef: boolean + dontAddTypeDef: boolean, + omitTyped = false ): string[] { - return names.map(([key, value]) => { - // Important to not use shorthand props for rename functionality - return `${dontAddTypeDef && value.doc ? `\n${value.doc}` : ''}${ - value.identifierText || key - }: ${key}`; - }); + return names + .map(([key, value]) => { + if (omitTyped && value.type) return; + // Important to not use shorthand props for rename functionality + return `${dontAddTypeDef && value.doc ? `\n${value.doc}` : ''}${ + value.identifierText || key + }: ${key}`; + }) + .filter(Boolean); } private createReturnElementsType( diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-export-list-runes.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-export-list-runes.v5/expectedv2.ts index 4f1adc400..d05d48969 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-export-list-runes.v5/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-export-list-runes.v5/expectedv2.ts @@ -20,7 +20,7 @@ ; async () => { { svelteHTML.createElement("svelte:options", {"runes":true,});} }; -return { props: {} as Record, exports: {} as any as { name1: string,name2: string,name3: string,name4: string,renamed1: string,renamed2: string,Foo: typeof Foo,bar: typeof bar,baz: string,RenamedFoo: typeof RenameFoo,renamedbar: typeof renamebar,renamedbaz: string }, bindings: __sveltets_$$bindings(''), slots: {}, events: {} }} +return { props: {} as Record, exports: {Foo: Foo,bar: bar,RenamedFoo: RenameFoo,renamedbar: renamebar} as any as { name1: string,name2: string,name3: string,name4: string,renamed1: string,renamed2: string,Foo: typeof Foo,bar: typeof bar,baz: string,RenamedFoo: typeof RenameFoo,renamedbar: typeof renamebar,renamedbaz: string }, bindings: __sveltets_$$bindings(''), slots: {}, events: {} }} const Input__SvelteComponent_ = __sveltets_2_fn_component($$render()); type Input__SvelteComponent_ = ReturnType; export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune.v5/expectedv2.ts index ce2a45ef9..4a33a614f 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune.v5/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune.v5/expectedv2.ts @@ -5,7 +5,7 @@ let { form, data }: $$ComponentProps = $props(); ; async () => {}; -return { props: {} as any as $$ComponentProps, exports: {} as any as { snapshot: typeof snapshot }, bindings: __sveltets_$$bindings(''), slots: {}, events: {} }} +return { props: {} as any as $$ComponentProps, exports: {snapshot: snapshot} as any as { snapshot: typeof snapshot }, bindings: __sveltets_$$bindings(''), slots: {}, events: {} }} const Page__SvelteComponent_ = __sveltets_2_fn_component($$render()); type Page__SvelteComponent_ = ReturnType; export default Page__SvelteComponent_; \ No newline at end of file