Skip to content

Commit

Permalink
fix: include named exports in svelte 5 type (#2528)
Browse files Browse the repository at this point in the history
  • Loading branch information
paoloricciuti authored Oct 9, 2024
1 parent 4dfb988 commit b12afd1
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 20 deletions.
10 changes: 5 additions & 5 deletions packages/svelte2tsx/repl/index.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<svelte:options runes />

<script>
export let value;
let name = "world"
let name2 = "world"
export { name as name3, name2 as name4 };
</script>

{#if value}
<input bind:value on:change />
{/if}
23 changes: 19 additions & 4 deletions packages/svelte2tsx/src/svelte2tsx/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type TemplateProcessResult = {
events: ComponentEvents;
resolvedStores: string[];
usesAccessors: boolean;
isRunes: boolean;
};

function processSvelteTemplate(
Expand All @@ -64,6 +65,7 @@ function processSvelteTemplate(
let uses$$restProps = false;
let uses$$slots = false;
let usesAccessors = !!options.accessors;
let isRunes = false;

const componentDocumentation = new ComponentDocumentation();

Expand Down Expand Up @@ -92,6 +94,9 @@ function processSvelteTemplate(
usesAccessors = true;
}
break;
case 'runes':
isRunes = true;
break;
}
}
};
Expand Down Expand Up @@ -303,7 +308,8 @@ function processSvelteTemplate(
uses$$slots,
componentDocumentation,
resolvedStores,
usesAccessors
usesAccessors,
isRunes
};
}

Expand Down Expand Up @@ -342,7 +348,8 @@ export function svelte2tsx(
events,
componentDocumentation,
resolvedStores,
usesAccessors
usesAccessors,
isRunes
} = processSvelteTemplate(str, options.parse || parse, {
...options,
svelte5Plus
Expand Down Expand Up @@ -370,7 +377,14 @@ export function svelte2tsx(
: instanceScriptTarget;
const implicitStoreValues = new ImplicitStoreValues(resolvedStores, renderFunctionStart);
//move the instance script and process the content
let exportedNames = new ExportedNames(str, 0, basename, options?.isTsFile, svelte5Plus);
let exportedNames = new ExportedNames(
str,
0,
basename,
options?.isTsFile,
svelte5Plus,
isRunes
);
let generics = new Generics(str, 0, { attributes: [] } as any);
let uses$$SlotsInterface = false;
if (scriptTag) {
Expand All @@ -387,7 +401,8 @@ export function svelte2tsx(
/**hasModuleScripts */ !!moduleScriptTag,
options?.isTsFile,
basename,
svelte5Plus
svelte5Plus,
isRunes
);
uses$$props = uses$$props || res.uses$$props;
uses$$restProps = uses$$restProps || res.uses$$restProps;
Expand Down
24 changes: 15 additions & 9 deletions packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ interface ExportedName {
identifierText?: string;
required?: boolean;
doc?: string;
isNamedExport?: boolean;
}

export class ExportedNames {
Expand Down Expand Up @@ -54,7 +55,8 @@ export class ExportedNames {
private astOffset: number,
private basename: string,
private isTsFile: boolean,
private isSvelte5Plus: boolean
private isSvelte5Plus: boolean,
private isRunes: boolean
) {}

handleVariableStatement(node: ts.VariableStatement, parent: ts.Node): void {
Expand Down Expand Up @@ -127,9 +129,9 @@ export class ExportedNames {
if (ts.isNamedExports(exportClause)) {
for (const ne of exportClause.elements) {
if (ne.propertyName) {
this.addExport(ne.propertyName, false, ne.name);
this.addExport(ne.propertyName, false, ne.name, undefined, undefined, true);
} else {
this.addExport(ne.name, false);
this.addExport(ne.name, false, undefined, undefined, undefined, true);
}
}
//we can remove entire statement
Expand Down Expand Up @@ -552,24 +554,26 @@ export class ExportedNames {
isLet: boolean,
target: ts.Identifier = null,
type: ts.TypeNode = null,
required = false
required = false,
isNamedExport = false
): void {
const existingDeclaration = this.possibleExports.get(name.text);

if (target) {
this.exports.set(name.text, {
isLet: isLet || existingDeclaration?.isLet,
type: type?.getText() || existingDeclaration?.type,
identifierText: target.text,
required: required || existingDeclaration?.required,
doc: this.getDoc(target) || existingDeclaration?.doc
doc: this.getDoc(target) || existingDeclaration?.doc,
isNamedExport
});
} else {
this.exports.set(name.text, {
isLet: isLet || existingDeclaration?.isLet,
type: existingDeclaration?.type,
required: existingDeclaration?.required,
doc: existingDeclaration?.doc
doc: existingDeclaration?.doc,
isNamedExport
});
}

Expand Down Expand Up @@ -706,7 +710,9 @@ export class ExportedNames {
*/
createExportsStr(): string {
const names = Array.from(this.exports.entries());
const others = names.filter(([, { isLet }]) => !isLet);
const others = names.filter(
([, { isLet, isNamedExport }]) => !isLet || (this.usesRunes() && isNamedExport)
);
const needsAccessors = this.usesAccessors && names.length > 0 && !this.usesRunes(); // runes mode doesn't support accessors

if (this.isSvelte5Plus) {
Expand Down Expand Up @@ -803,6 +809,6 @@ export class ExportedNames {
}

usesRunes() {
return this.hasRunesGlobals || this.hasPropsRune();
return this.hasRunesGlobals || this.hasPropsRune() || this.isRunes;
}
}
12 changes: 10 additions & 2 deletions packages/svelte2tsx/src/svelte2tsx/processInstanceScriptContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ export function processInstanceScriptContent(
hasModuleScript: boolean,
isTSFile: boolean,
basename: string,
isSvelte5Plus: boolean
isSvelte5Plus: boolean,
isRunes: boolean
): InstanceScriptProcessResult {
const htmlx = str.original;
const scriptContent = htmlx.substring(script.content.start, script.content.end);
Expand All @@ -54,7 +55,14 @@ export function processInstanceScriptContent(
ts.ScriptKind.TS
);
const astOffset = script.content.start;
const exportedNames = new ExportedNames(str, astOffset, basename, isTSFile, isSvelte5Plus);
const exportedNames = new ExportedNames(
str,
astOffset,
basename,
isTSFile,
isSvelte5Plus,
isRunes
);
const generics = new Generics(str, astOffset, script);
const interfacesAndTypes = new InterfacesAndTypes();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
///<reference types="svelte" />
;function render() {

let name1 = "world"
let name2/*Ωignore_startΩ*/;name2 = __sveltets_2_any(name2);/*Ωignore_endΩ*/

let rename1 = '';
let rename2/*Ωignore_startΩ*/;rename2 = __sveltets_2_any(rename2);/*Ωignore_endΩ*/;

class Foo {}
function bar() {}
const baz = '';

class RenameFoo {}
function renamebar() {}
const renamebaz = '';


;
async () => { { svelteHTML.createElement("svelte:options", {"runes":true,});}

};
return { props: /** @type {Record<string, never>} */ ({}), exports: /** @type {{name1: typeof name1,name2: typeof name2,renamed1: typeof rename1,renamed2: typeof rename2,Foo: typeof Foo,bar: typeof bar,baz: typeof baz,RenamedFoo: typeof RenameFoo,renamedbar: typeof renamebar,renamedbaz: typeof renamebaz}} */ ({}), bindings: __sveltets_$$bindings(''), slots: {}, events: {} }}
const Input__SvelteComponent_ = __sveltets_2_fn_component(render());
export default Input__SvelteComponent_;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<svelte:options runes />

<script>
let name1 = "world"
let name2
let rename1 = '';
let rename2;
class Foo {}
function bar() {}
const baz = '';
class RenameFoo {}
function renamebar() {}
const renamebaz = '';
export { name1, name2, rename1 as renamed1, rename2 as renamed2, Foo, bar, baz, RenameFoo as RenamedFoo, renamebar as renamedbar, renamebaz as renamedbaz };
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
///<reference types="svelte" />
;function render() {

let name = "world"
let name2 = "world"

;
async () => { { svelteHTML.createElement("svelte:options", {"runes":true,});}

};
return { props: /** @type {Record<string, never>} */ ({}), exports: /** @type {{name3: typeof name,name4: typeof name2}} */ ({}), bindings: __sveltets_$$bindings(''), slots: {}, events: {} }}
const Input__SvelteComponent_ = __sveltets_2_fn_component(render());
export default Input__SvelteComponent_;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<svelte:options runes />

<script>
let name = "world"
let name2 = "world"
export { name as name3, name2 as name4 };
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
///<reference types="svelte" />
;function render() {

let name1: string = "world"/*Ωignore_startΩ*/;name1 = __sveltets_2_any(name1);/*Ωignore_endΩ*/
let name2: string/*Ωignore_startΩ*/;name2 = __sveltets_2_any(name2);/*Ωignore_endΩ*/;
let name3: string = ''/*Ωignore_startΩ*/;name3 = __sveltets_2_any(name3);/*Ωignore_endΩ*/;let name4: string/*Ωignore_startΩ*/;name4 = __sveltets_2_any(name4);/*Ωignore_endΩ*/;

let rename1: string = ''/*Ωignore_startΩ*/;rename1 = __sveltets_2_any(rename1);/*Ωignore_endΩ*/;
let rename2: string/*Ωignore_startΩ*/;rename2 = __sveltets_2_any(rename2);/*Ωignore_endΩ*/;

class Foo {}
function bar() {}
const baz: string = '';

class RenameFoo {}
function renamebar() {}
const renamebaz: string = '';


;
async () => { { svelteHTML.createElement("svelte:options", {"runes":true,});}
};
return { props: {} as Record<string, never>, 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: {} }}
const Input__SvelteComponent_ = __sveltets_2_fn_component(render());
export default Input__SvelteComponent_;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<svelte:options runes />
<script>
let name1: string = "world"
let name2: string;
let name3: string = '', name4: string;
let rename1: string = '';
let rename2: string;
class Foo {}
function bar() {}
const baz: string = '';
class RenameFoo {}
function renamebar() {}
const renamebaz: string = '';
export { name1, name2, name3, name4, rename1 as renamed1, rename2 as renamed2, Foo, bar, baz, RenameFoo as RenamedFoo, renamebar as renamedbar, renamebaz as renamedbaz };
</script>

0 comments on commit b12afd1

Please sign in to comment.