From 2478212c7f9e61153f893d1c257c33bde68a354f Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Wed, 29 May 2024 16:48:22 +0200 Subject: [PATCH] feat: Svelte 5 component class/function interop (#2380) Svelte 5 uses functions to define components under the hood. This should be represented in the types. We can't just switch to using functions though because d.ts files created from Svelte 4 libraries should still work, and those contain classes. So we need interop between functions and classes. The idea is therefore: Svelte 5 creates a default export which is both a function and a class constructor Various places are adjusted to support the new default exports Also see https://github.com/sveltejs/svelte/pull/11775 --- .../typescript/ComponentInfoProvider.ts | 7 +- .../plugins/typescript/DocumentSnapshot.ts | 5 +- .../typescript/features/CompletionProvider.ts | 21 ++- .../features/DiagnosticsProvider.ts | 12 +- .../features/FindReferencesProvider.ts | 21 ++- .../typescript/features/HoverProvider.ts | 11 +- .../src/plugins/typescript/features/utils.ts | 37 +++- .../features/CallHierarchyProvider.test.ts | 12 ++ .../features/CodeActionsProvider.test.ts | 13 ++ .../features/CompletionProvider.test.ts | 16 +- .../FindComponentReferencesProvider.test.ts | 36 ++-- .../features/FindReferencesProvider.test.ts | 30 +-- .../features/SemanticTokensProvider.test.ts | 7 +- .../fixtures/bindings/expectedv2.json | 71 ++++++- .../fixtures/bindings/input.svelte | 2 +- .../component-invalid/components.d.ts | 2 + .../component-invalid/expected_svelte_5.json | 57 ++++++ .../fixtures/component-invalid/input.svelte | 6 +- packages/svelte2tsx/repl/debug.ts | 15 +- packages/svelte2tsx/src/emitDts.ts | 11 +- .../src/svelte2tsx/addComponentExport.ts | 177 +++++++++++------- packages/svelte2tsx/src/svelte2tsx/index.ts | 9 +- .../src/svelte2tsx/nodes/ExportedNames.ts | 82 +++++--- .../src/svelte2tsx/nodes/Generics.ts | 4 + .../processInstanceScriptContent.ts | 5 +- packages/svelte2tsx/svelte-shims-v4.d.ts | 57 ++++-- .../expected/TestRunes.svelte.d.ts | 21 +++ .../samples/javascript-runes.v5/jsconfig.json | 6 + .../javascript-runes.v5/src/TestRunes.svelte | 5 + .../expected/TestRunes.svelte.d.ts | 27 +++ .../src/TestRunes.svelte | 5 + .../tsconfig.json | 14 ++ .../expected/TestRunes.svelte.d.ts | 42 ++--- packages/svelte2tsx/test/helpers.ts | 47 +++-- .../accessors-config/expected-svelte5.ts | 10 + .../expected-svelte5.ts | 14 -- .../expected-svelte5.ts | 18 -- .../expected-svelte5.ts | 24 --- .../expected-svelte5.ts | 24 --- .../expected-svelte5.ts | 14 -- .../expected-svelte5.ts | 11 -- .../expected-svelte5.ts | 6 +- .../expected-svelte5.ts | 15 -- .../expected-svelte5.ts | 13 -- .../expected-svelte5.ts | 12 -- .../expected-svelte5.ts | 6 +- .../expected-svelte5.ts | 6 +- .../expected-svelte5.ts | 6 +- .../expected-svelte5.ts | 10 - .../expected-svelte5.ts | 10 - .../expected-svelte5.ts | 10 + .../expected-svelte5.ts | 22 +++ .../expected-svelte5.ts | 16 ++ .../const-tag-component/expected-svelte5.ts | 6 +- .../samples/creates-dts/expected-svelte5.ts | 24 ++- .../creates-no-script-dts/expected-svelte5.ts | 24 ++- .../samples/export-class/expected-svelte5.ts | 10 + .../expected-svelte5.ts | 12 ++ .../expected-svelte5.ts | 21 +++ .../samples/export-list/expected-svelte5.ts | 24 +++ .../expected-svelte5.ts | 29 +++ .../runes-best-effort-types.v5/expectedv2.ts | 10 + .../input.svelte | 0 .../runes-best-effort-types/expectedv2.ts | 12 -- .../samples/runes-bindable.v5/expectedv2.ts | 10 + .../input.svelte | 0 .../samples/runes-bindable/expectedv2.ts | 12 -- .../expectedv2.ts | 14 ++ .../input.svelte | 0 .../runes-looking-like-stores/expectedv2.ts | 16 -- .../runes-only-export.v5/expectedv2.ts | 9 +- .../samples/runes-with-slots.v5/expectedv2.ts | 16 ++ .../input.svelte | 0 .../samples/runes-with-slots/expectedv2.ts | 17 -- .../svelte2tsx/samples/runes.v5/expectedv2.ts | 13 ++ .../samples/{runes => runes.v5}/input.svelte | 0 .../svelte2tsx/samples/runes/expectedv2.ts | 15 -- .../expected-svelte5.ts | 6 +- .../svelte-element/expected-svelte5.ts | 6 +- .../+page.svelte | 0 .../expectedv2.ts | 13 ++ .../expectedv2.ts | 16 -- .../+page.svelte | 0 .../expected-svelte5.ts | 11 ++ .../expectedv2.ts | 11 ++ .../expectedv2.ts | 14 -- .../sveltekit-autotypes/expected-svelte5.ts | 16 ++ .../expected-svelte5.ts | 36 ++++ .../ts-$$Props-interface/expected-svelte5.ts | 37 ++++ .../ts-$$Props-type/expected-svelte5.ts | 37 ++++ .../expected-svelte5.ts | 19 ++ .../expected-svelte5.ts | 34 ++++ .../expected-svelte5.ts | 33 ++++ .../ts-$$generics-dts/expected-svelte5.ts | 18 +- .../expected-svelte5.ts | 45 +++++ .../samples/ts-$$generics/expected-svelte5.ts | 17 +- .../ts-creates-dts/expected-svelte5.ts | 24 ++- .../ts-export-const/expected-svelte5.ts | 11 ++ .../ts-export-list/expected-svelte5.ts | 25 +++ .../expected-svelte5.ts | 17 +- .../expected-svelte5.ts | 29 +++ .../expectedv2.ts | 10 +- .../input.svelte | 0 .../ts-runes-bindable.v5/expectedv2.ts | 10 + .../input.svelte | 0 .../samples/ts-runes-bindable/expectedv2.ts | 12 -- .../ts-runes-generics.v5/expectedv2.ts | 31 +++ .../input.svelte | 0 .../samples/ts-runes-generics/expectedv2.ts | 27 --- .../ts-runes-with-slot.v5/expectedv2.ts | 35 ++++ .../input.svelte | 0 .../samples/ts-runes-with-slot/expectedv2.ts | 30 --- .../samples/ts-runes.v5/expectedv2.ts | 12 ++ .../{ts-runes => ts-runes.v5}/input.svelte | 0 .../svelte2tsx/samples/ts-runes/expectedv2.ts | 14 -- .../expected-svelte5.ts | 29 +++ .../+page.svelte | 0 .../expectedv2.ts | 11 ++ .../expectedv2.ts | 14 -- .../+page.svelte | 0 .../expectedv2.ts | 11 +- .../uses-$$slots-script/expected-svelte5.ts | 17 -- .../samples/uses-$$slots/expected-svelte5.ts | 13 -- .../expected-svelte5.ts | 12 ++ .../expected-svelte5.ts | 15 ++ .../expected-svelte5.ts | 12 ++ .../expected-svelte5.ts | 15 ++ .../expected-svelte5.ts | 11 ++ .../expected-svelte5.ts | 6 +- .../expected-svelte5.ts | 6 +- 130 files changed, 1565 insertions(+), 697 deletions(-) create mode 100644 packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/component-invalid/expected_svelte_5.json create mode 100644 packages/svelte2tsx/test/emitDts/samples/javascript-runes.v5/expected/TestRunes.svelte.d.ts create mode 100644 packages/svelte2tsx/test/emitDts/samples/javascript-runes.v5/jsconfig.json create mode 100644 packages/svelte2tsx/test/emitDts/samples/javascript-runes.v5/src/TestRunes.svelte create mode 100644 packages/svelte2tsx/test/emitDts/samples/typescript-runes-generics.v5/expected/TestRunes.svelte.d.ts create mode 100644 packages/svelte2tsx/test/emitDts/samples/typescript-runes-generics.v5/src/TestRunes.svelte create mode 100644 packages/svelte2tsx/test/emitDts/samples/typescript-runes-generics.v5/tsconfig.json create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/accessors-config/expected-svelte5.ts delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/component-default-slot/expected-svelte5.ts delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/component-multiple-slots/expected-svelte5.ts delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/component-slot-$$slot-interface/expected-svelte5.ts delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/component-slot-$$slot-type/expected-svelte5.ts delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/component-slot-crazy-attributes/expected-svelte5.ts delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/component-slot-fallback/expected-svelte5.ts delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/component-slot-inside-await/expected-svelte5.ts delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/component-slot-inside-each/expected-svelte5.ts delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/component-slot-let-forward-named-slot/expected-svelte5.ts delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/component-slot-object-key/expected-svelte5.ts delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/component-slot-var-shadowing/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/component-with-documentation/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/component-with-indented-multiline-documentation/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/component-with-multiline-documentation/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/export-class/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/export-const-array-destructuring/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/export-const-object-destructuring/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/export-list/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/generic-attribute-const-modifier/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types.v5/expectedv2.ts rename packages/svelte2tsx/test/svelte2tsx/samples/{runes-best-effort-types => runes-best-effort-types.v5}/input.svelte (100%) delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types/expectedv2.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable.v5/expectedv2.ts rename packages/svelte2tsx/test/svelte2tsx/samples/{runes-bindable => runes-bindable.v5}/input.svelte (100%) delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable/expectedv2.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores.v5/expectedv2.ts rename packages/svelte2tsx/test/svelte2tsx/samples/{runes-looking-like-stores => runes-looking-like-stores.v5}/input.svelte (100%) delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores/expectedv2.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/runes-with-slots.v5/expectedv2.ts rename packages/svelte2tsx/test/svelte2tsx/samples/{runes-with-slots => runes-with-slots.v5}/input.svelte (100%) delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/runes-with-slots/expectedv2.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/runes.v5/expectedv2.ts rename packages/svelte2tsx/test/svelte2tsx/samples/{runes => runes.v5}/input.svelte (100%) delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/runes/expectedv2.ts rename packages/svelte2tsx/test/svelte2tsx/samples/{sveltekit-autotypes-$props-rune-no-changes => sveltekit-autotypes-$props-rune-no-changes.v5}/+page.svelte (100%) create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune-no-changes.v5/expectedv2.ts delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune-no-changes/expectedv2.ts rename packages/svelte2tsx/test/svelte2tsx/samples/{sveltekit-autotypes-$props-rune => sveltekit-autotypes-$props-rune.v5}/+page.svelte (100%) create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune.v5/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune.v5/expectedv2.ts delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune/expectedv2.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/transforms-interfaces-dts/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-interface/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-type/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-with-$$props/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics-accessor-dts/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics-accessor/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics-interface-references/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-export-const/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-export-list/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-generics-attribute2/expected-svelte5.ts rename packages/svelte2tsx/test/svelte2tsx/samples/{ts-runes-best-effort-types => ts-runes-best-effort-types.v5}/expectedv2.ts (51%) rename packages/svelte2tsx/test/svelte2tsx/samples/{ts-runes-best-effort-types => ts-runes-best-effort-types.v5}/input.svelte (100%) create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-bindable.v5/expectedv2.ts rename packages/svelte2tsx/test/svelte2tsx/samples/{ts-runes-bindable => ts-runes-bindable.v5}/input.svelte (100%) delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-bindable/expectedv2.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-generics.v5/expectedv2.ts rename packages/svelte2tsx/test/svelte2tsx/samples/{ts-runes-generics => ts-runes-generics.v5}/input.svelte (100%) delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-generics/expectedv2.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-with-slot.v5/expectedv2.ts rename packages/svelte2tsx/test/svelte2tsx/samples/{ts-runes-with-slot => ts-runes-with-slot.v5}/input.svelte (100%) delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-with-slot/expectedv2.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-runes.v5/expectedv2.ts rename packages/svelte2tsx/test/svelte2tsx/samples/{ts-runes => ts-runes.v5}/input.svelte (100%) delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-runes/expectedv2.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-script-tag-generics/expected-svelte5.ts rename packages/svelte2tsx/test/svelte2tsx/samples/{ts-sveltekit-autotypes-$props-rune-unchanged => ts-sveltekit-autotypes-$props-rune-unchanged.v5}/+page.svelte (100%) create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune-unchanged.v5/expectedv2.ts delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune-unchanged/expectedv2.ts rename packages/svelte2tsx/test/svelte2tsx/samples/{ts-sveltekit-autotypes-$props-rune => ts-sveltekit-autotypes-$props-rune.v5}/+page.svelte (100%) rename packages/svelte2tsx/test/svelte2tsx/samples/{ts-sveltekit-autotypes-$props-rune => ts-sveltekit-autotypes-$props-rune.v5}/expectedv2.ts (51%) delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/uses-$$slots-script/expected-svelte5.ts delete mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/uses-$$slots/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-attr-not-present/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-attr-present/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-mustachetag-false/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-mustachetag-true/expected-svelte5.ts create mode 100644 packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-no-svelte-options/expected-svelte5.ts diff --git a/packages/language-server/src/plugins/typescript/ComponentInfoProvider.ts b/packages/language-server/src/plugins/typescript/ComponentInfoProvider.ts index a28f89368..733a85506 100644 --- a/packages/language-server/src/plugins/typescript/ComponentInfoProvider.ts +++ b/packages/language-server/src/plugins/typescript/ComponentInfoProvider.ts @@ -95,7 +95,12 @@ export class JsOrTsComponentInfoProvider implements ComponentInfoProvider { return null; } - const defClass = findContainingNode(sourceFile, def.textSpan, ts.isClassDeclaration); + const defClass = findContainingNode( + sourceFile, + def.textSpan, + (node): node is ts.ClassDeclaration | ts.VariableDeclaration => + ts.isClassDeclaration(node) || ts.isTypeAliasDeclaration(node) + ); if (!defClass) { return null; diff --git a/packages/language-server/src/plugins/typescript/DocumentSnapshot.ts b/packages/language-server/src/plugins/typescript/DocumentSnapshot.ts index d5d921af5..c0d21d282 100644 --- a/packages/language-server/src/plugins/typescript/DocumentSnapshot.ts +++ b/packages/language-server/src/plugins/typescript/DocumentSnapshot.ts @@ -268,6 +268,7 @@ export class SvelteDocumentSnapshot implements DocumentSnapshot { private url = pathToUrl(this.filePath); version = this.parent.version; + isSvelte5Plus = Number(this.svelteVersion?.split('.')[0]) >= 5; constructor( public readonly parent: Document, @@ -281,10 +282,6 @@ export class SvelteDocumentSnapshot implements DocumentSnapshot { private readonly htmlAst?: TemplateNode ) {} - get isSvelte5Plus() { - return Number(this.svelteVersion?.split('.')[0]) >= 5; - } - get filePath() { return this.parent.getFilePath() || ''; } diff --git a/packages/language-server/src/plugins/typescript/features/CompletionProvider.ts b/packages/language-server/src/plugins/typescript/features/CompletionProvider.ts index 7fc0bb283..497d000af 100644 --- a/packages/language-server/src/plugins/typescript/features/CompletionProvider.ts +++ b/packages/language-server/src/plugins/typescript/features/CompletionProvider.ts @@ -851,7 +851,7 @@ export class CompletionsProviderImpl implements CompletionsProvider codeAction.description) ?? []; @@ -910,7 +914,18 @@ export class CompletionsProviderImpl implements CompletionsProvider {}' + (isSvelte5Plus + ? '' + : 'If you are using Svelte 3.31+, use SvelteComponentTyped to add a definition:\n' + + ' import type { SvelteComponentTyped } from "svelte";\n' + + ' class ComponentName extends SvelteComponentTyped<{propertyName: string;}> {}') }; } diff --git a/packages/language-server/src/plugins/typescript/features/FindReferencesProvider.ts b/packages/language-server/src/plugins/typescript/features/FindReferencesProvider.ts index c530398ea..5f67fd61b 100644 --- a/packages/language-server/src/plugins/typescript/features/FindReferencesProvider.ts +++ b/packages/language-server/src/plugins/typescript/features/FindReferencesProvider.ts @@ -168,7 +168,26 @@ export class FindReferencesProviderImpl implements FindReferencesProvider { ) ); - return flatten(references.filter(isNotNullOrUndefined)); + const flattened: Location[] = []; + for (const ref of references) { + if (ref) { + const tmp: Location[] = []; // perf optimization: we know each iteration has unique references + for (const r of ref) { + const exists = flattened.some( + (f) => + f.uri === r.uri && + f.range.start.line === r.range.start.line && + f.range.start.character === r.range.start.character + ); + if (!exists) { + tmp.push(r); + } + } + flattened.push(...tmp); + } + } + + return flattened; } private async mapReference( diff --git a/packages/language-server/src/plugins/typescript/features/HoverProvider.ts b/packages/language-server/src/plugins/typescript/features/HoverProvider.ts index feebf5717..ebd9f69c6 100644 --- a/packages/language-server/src/plugins/typescript/features/HoverProvider.ts +++ b/packages/language-server/src/plugins/typescript/features/HoverProvider.ts @@ -25,7 +25,16 @@ export class HoverProviderImpl implements HoverProvider { return null; } - const declaration = ts.displayPartsToString(info.displayParts); + let declaration = ts.displayPartsToString(info.displayParts); + if ( + tsDoc.isSvelte5Plus && + declaration.includes('(alias)') && + declaration.includes('__sveltets_2_IsomorphicComponent') + ) { + // info ends with "import ComponentName" + declaration = declaration.substring(declaration.lastIndexOf('import')); + } + const documentation = getMarkdownDocumentation(info.documentation, info.tags); // https://microsoft.github.io/language-server-protocol/specification#textDocument_hover diff --git a/packages/language-server/src/plugins/typescript/features/utils.ts b/packages/language-server/src/plugins/typescript/features/utils.ts index bd2e5cc7e..696964d8a 100644 --- a/packages/language-server/src/plugins/typescript/features/utils.ts +++ b/packages/language-server/src/plugins/typescript/features/utils.ts @@ -50,21 +50,42 @@ export function getComponentAtPosition( doc.positionAt(node.start + symbolPosWithinNode + 1) ); - let def = lang.getDefinitionAtPosition(tsDoc.filePath, tsDoc.offsetAt(generatedPosition))?.[0]; - - while (def != null && def.kind !== ts.ScriptElementKind.classElement) { - const newDef = lang.getDefinitionAtPosition(tsDoc.filePath, def.textSpan.start)?.[0]; - if (newDef?.fileName === def.fileName && newDef?.textSpan.start === def.textSpan.start) { + let defs = lang.getDefinitionAtPosition(tsDoc.filePath, tsDoc.offsetAt(generatedPosition)); + // Svelte 5 uses a const and a type alias instead of a class, and we want the latter. + // We still gotta check for a class in Svelte 5 because of d.ts files generated for Svelte 4 containing classes. + let def1 = defs?.[0]; + let def2 = tsDoc.isSvelte5Plus ? defs?.[1] : undefined; + + while ( + def1 != null && + def1.kind !== ts.ScriptElementKind.classElement && + (def2 == null || + def2.kind !== ts.ScriptElementKind.constElement || + !def2.name.endsWith('__SvelteComponent_')) + ) { + const newDefs = lang.getDefinitionAtPosition(tsDoc.filePath, def1.textSpan.start); + const newDef = newDefs?.[0]; + if (newDef?.fileName === def1.fileName && newDef?.textSpan.start === def1.textSpan.start) { break; } - def = newDef; + defs = newDefs; + def1 = newDef; + def2 = tsDoc.isSvelte5Plus ? newDefs?.[1] : undefined; } - if (!def) { + if (!def1 && !def2) { return null; } - return JsOrTsComponentInfoProvider.create(lang, def); + if ( + def2 != null && + def2.kind === ts.ScriptElementKind.constElement && + def2.name.endsWith('__SvelteComponent_') + ) { + def1 = undefined; + } + + return JsOrTsComponentInfoProvider.create(lang, def1! || def2!); } export function isComponentAtPosition( diff --git a/packages/language-server/test/plugins/typescript/features/CallHierarchyProvider.test.ts b/packages/language-server/test/plugins/typescript/features/CallHierarchyProvider.test.ts index 51ce09449..65f388b81 100644 --- a/packages/language-server/test/plugins/typescript/features/CallHierarchyProvider.test.ts +++ b/packages/language-server/test/plugins/typescript/features/CallHierarchyProvider.test.ts @@ -14,8 +14,10 @@ import { LSAndTSDocResolver } from '../../../../src/plugins/typescript/LSAndTSDo import { __resetCache } from '../../../../src/plugins/typescript/service'; import { pathToUrl } from '../../../../src/utils'; import { serviceWarmup } from '../test-utils'; +import { VERSION } from 'svelte/compiler'; const testDir = path.join(__dirname, '..'); +const isSvelte5Plus = +VERSION.split('.')[0] >= 5; describe('CallHierarchyProvider', function () { const callHierarchyTestDirRelative = path.join('testfiles', 'call-hierarchy'); @@ -386,6 +388,11 @@ describe('CallHierarchyProvider', function () { }); it('can provide outgoing calls for component file', async () => { + if (isSvelte5Plus) { + // Doesn't work due to https://github.com/microsoft/TypeScript/issues/43740 and https://github.com/microsoft/TypeScript/issues/42375 + return; + } + const { provider, document } = setup(outgoingComponentName); const items = await provider.prepareCallHierarchy(document, { line: 10, character: 1 }); @@ -411,6 +418,11 @@ describe('CallHierarchyProvider', function () { }); it('can provide outgoing calls for component tags', async () => { + if (isSvelte5Plus) { + // Doesn't work due to https://github.com/microsoft/TypeScript/issues/43740 and https://github.com/microsoft/TypeScript/issues/42375 + return; + } + const { provider, document } = setup(outgoingComponentName); const items = await provider.prepareCallHierarchy(document, { line: 0, character: 2 }); diff --git a/packages/language-server/test/plugins/typescript/features/CodeActionsProvider.test.ts b/packages/language-server/test/plugins/typescript/features/CodeActionsProvider.test.ts index 80c896949..9c4f9494d 100644 --- a/packages/language-server/test/plugins/typescript/features/CodeActionsProvider.test.ts +++ b/packages/language-server/test/plugins/typescript/features/CodeActionsProvider.test.ts @@ -21,9 +21,11 @@ import { __resetCache } from '../../../../src/plugins/typescript/service'; import { pathToUrl } from '../../../../src/utils'; import { recursiveServiceWarmup } from '../test-utils'; import { DiagnosticCode } from '../../../../src/plugins/typescript/features/DiagnosticsProvider'; +import { VERSION } from 'svelte/compiler'; const testDir = path.join(__dirname, '..'); const indent = ' '.repeat(4); +const isSvelte5Plus = +VERSION.split('.')[0] >= 5; describe('CodeActionsProvider', function () { recursiveServiceWarmup( @@ -374,6 +376,17 @@ describe('CodeActionsProvider', function () { uri: getUri('codeaction-checkJs.svelte'), version: null }; + + if (isSvelte5Plus) { + // Maybe because of the hidden interface declarations? It's harmless anyway + if ( + codeActions.length === 4 && + codeActions[3].title === "Add '@ts-ignore' to all error messages" + ) { + codeActions.splice(3, 1); + } + } + assert.deepStrictEqual(codeActions, [ { edit: { diff --git a/packages/language-server/test/plugins/typescript/features/CompletionProvider.test.ts b/packages/language-server/test/plugins/typescript/features/CompletionProvider.test.ts index 419b03f49..682a0ec8d 100644 --- a/packages/language-server/test/plugins/typescript/features/CompletionProvider.test.ts +++ b/packages/language-server/test/plugins/typescript/features/CompletionProvider.test.ts @@ -24,11 +24,13 @@ import { sortBy } from 'lodash'; import { LSConfigManager } from '../../../../src/ls-config'; import { __resetCache } from '../../../../src/plugins/typescript/service'; import { getRandomVirtualDirPath, serviceWarmup, setupVirtualEnvironment } from '../test-utils'; +import { VERSION } from 'svelte/compiler'; const testDir = join(__dirname, '..'); const testFilesDir = join(testDir, 'testfiles', 'completions'); const newLine = ts.sys.newLine; const indent = ' '.repeat(4); +const isSvelte5Plus = +VERSION.split('.')[0] >= 5; const fileNameToAbsoluteUri = (file: string) => { return pathToUrl(join(testFilesDir, file)); @@ -855,7 +857,7 @@ describe('CompletionProviderImpl', function () { assert.strictEqual( detail, - 'Add import from "../imported-file.svelte"\n\nclass ImportedFile' + `Add import from "../imported-file.svelte"${isSvelte5Plus ? '' : '\n\nclass ImportedFile'}` ); assert.strictEqual( @@ -893,7 +895,7 @@ describe('CompletionProviderImpl', function () { assert.strictEqual( detail, - 'Add import from "../imported-file.svelte"\n\nclass ImportedFile' + `Add import from "../imported-file.svelte"${isSvelte5Plus ? '' : '\n\nclass ImportedFile'}` ); assert.strictEqual( @@ -1502,7 +1504,10 @@ describe('CompletionProviderImpl', function () { const item2 = completions2?.items.find((item) => item.label === 'Bar'); const { detail } = await completionProvider.resolveCompletion(document, item2!); - assert.strictEqual(detail, 'Add import from "./Bar.svelte"\n\nclass Bar'); + assert.strictEqual( + detail, + `Add import from "./Bar.svelte"${isSvelte5Plus ? '' : '\n\nclass Bar'}` + ); }); it("doesn't use empty cache", async () => { @@ -1551,7 +1556,10 @@ describe('CompletionProviderImpl', function () { const item2 = completions?.items.find((item) => item.label === 'Bar'); const { detail } = await completionProvider.resolveCompletion(document, item2!); - assert.strictEqual(detail, 'Add import from "./Bar.svelte"\n\nclass Bar'); + assert.strictEqual( + detail, + `Add import from "./Bar.svelte"${isSvelte5Plus ? '' : '\n\nclass Bar'}` + ); }); it('can auto import new export', async () => { diff --git a/packages/language-server/test/plugins/typescript/features/FindComponentReferencesProvider.test.ts b/packages/language-server/test/plugins/typescript/features/FindComponentReferencesProvider.test.ts index 25b38235e..eda677cd0 100644 --- a/packages/language-server/test/plugins/typescript/features/FindComponentReferencesProvider.test.ts +++ b/packages/language-server/test/plugins/typescript/features/FindComponentReferencesProvider.test.ts @@ -7,8 +7,11 @@ import { FindComponentReferencesProviderImpl } from '../../../../src/plugins/typ import { LSAndTSDocResolver } from '../../../../src/plugins/typescript/LSAndTSDocResolver'; import { pathToUrl } from '../../../../src/utils'; import { serviceWarmup } from '../test-utils'; +import { Location } from 'vscode-html-languageservice'; +import { VERSION } from 'svelte/compiler'; const testDir = path.join(__dirname, '..', 'testfiles'); +const isSvelte5Plus = +VERSION.split('.')[0] >= 5; describe('FindComponentReferencesProvider', function () { serviceWarmup(this, testDir); @@ -54,20 +57,7 @@ describe('FindComponentReferencesProvider', function () { const results = await provider.findComponentReferences(document.uri.toString()); - assert.deepStrictEqual(results, [ - { - range: { - start: { - line: 8, - character: 15 - }, - end: { - line: 8, - character: 22 - } - }, - uri: getUri('find-component-references-parent.svelte') - }, + const expected: Location[] = [ { range: { start: { @@ -120,6 +110,22 @@ describe('FindComponentReferencesProvider', function () { }, uri: getUri('find-component-references-parent2.svelte') } - ]); + ]; + if (!isSvelte5Plus) { + expected.unshift({ + range: { + start: { + line: 8, + character: 15 + }, + end: { + line: 8, + character: 22 + } + }, + uri: getUri('find-component-references-parent.svelte') + }); + } + assert.deepStrictEqual(results, expected); }); }); diff --git a/packages/language-server/test/plugins/typescript/features/FindReferencesProvider.test.ts b/packages/language-server/test/plugins/typescript/features/FindReferencesProvider.test.ts index c68e3679a..ecd5d4f5b 100644 --- a/packages/language-server/test/plugins/typescript/features/FindReferencesProvider.test.ts +++ b/packages/language-server/test/plugins/typescript/features/FindReferencesProvider.test.ts @@ -10,8 +10,10 @@ import { __resetCache } from '../../../../src/plugins/typescript/service'; import { pathToUrl } from '../../../../src/utils'; import { serviceWarmup } from '../test-utils'; import { FindComponentReferencesProviderImpl } from '../../../../src/plugins/typescript/features/FindComponentReferencesProvider'; +import { VERSION } from 'svelte/compiler'; const testDir = path.join(__dirname, '..'); +const isSvelte5Plus = +VERSION.split('.')[0] >= 5; describe('FindReferencesProvider', function () { serviceWarmup(this, testDir); @@ -335,19 +337,6 @@ describe('FindReferencesProvider', function () { }); const componentReferences = [ - { - range: { - start: { - line: 8, - character: 15 - }, - end: { - line: 8, - character: 22 - } - }, - uri: getUri('find-component-references-parent.svelte') - }, { range: { start: { @@ -401,6 +390,21 @@ describe('FindReferencesProvider', function () { uri: getUri('find-component-references-parent2.svelte') } ]; + if (!isSvelte5Plus) { + componentReferences.unshift({ + range: { + start: { + line: 8, + character: 15 + }, + end: { + line: 8, + character: 22 + } + }, + uri: getUri('find-component-references-parent.svelte') + }); + } it('can find component references from script tag', async () => { const { provider, document, openDoc } = setup('find-component-references-child.svelte'); diff --git a/packages/language-server/test/plugins/typescript/features/SemanticTokensProvider.test.ts b/packages/language-server/test/plugins/typescript/features/SemanticTokensProvider.test.ts index 8b585fb4e..7acb27099 100644 --- a/packages/language-server/test/plugins/typescript/features/SemanticTokensProvider.test.ts +++ b/packages/language-server/test/plugins/typescript/features/SemanticTokensProvider.test.ts @@ -14,9 +14,11 @@ import { SemanticTokensProviderImpl } from '../../../../src/plugins/typescript/f import { LSAndTSDocResolver } from '../../../../src/plugins/typescript/LSAndTSDocResolver'; import { pathToUrl } from '../../../../src/utils'; import { serviceWarmup } from '../test-utils'; +import { VERSION } from 'svelte/compiler'; const testDir = path.join(__dirname, '..'); const semanticTokenTestDir = path.join(testDir, 'testfiles', 'semantic-tokens'); +const isSvelte5Plus = +VERSION.split('.')[0] >= 5; describe('SemanticTokensProvider', function () { const tsFile = 'tokens.svelte'; @@ -40,7 +42,6 @@ describe('SemanticTokensProvider', function () { return { provider, document }; } - // TODO reenable with updated tokens for new transformation it('provides semantic token', async () => { const { provider, document } = setup(tsFile); @@ -194,8 +195,8 @@ describe('SemanticTokensProvider', function () { line: 12, character: 5, length: 'Imported'.length, - type: TokenType.class, - modifiers: [] + type: isSvelte5Plus ? TokenType.type : TokenType.class, + modifiers: isSvelte5Plus ? [TokenModifier.readonly] : [] }, { line: 12, diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bindings/expectedv2.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bindings/expectedv2.json index fe51488c7..e441ca7e2 100644 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bindings/expectedv2.json +++ b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bindings/expectedv2.json @@ -1 +1,70 @@ -[] +[ + { + "code": 2353, + "message": "Object literal may only specify known properties, and 'can_bind' does not exist in type '{ only_bind?: (() => boolean) | undefined; }'.", + "range": { + "end": { + "character": 20, + "line": 20 + }, + "start": { + "character": 12, + "line": 20 + } + }, + "severity": 1, + "source": "ts", + "tags": [] + }, + { + "code": 2353, + "message": "Object literal may only specify known properties, and 'can_bind' does not exist in type '{ only_bind?: (() => boolean) | undefined; }'.", + "range": { + "end": { + "character": 16, + "line": 21 + }, + "start": { + "character": 8, + "line": 21 + } + }, + "severity": 1, + "source": "ts", + "tags": [] + }, + { + "code": 2353, + "message": "Object literal may only specify known properties, and 'readonly' does not exist in type '{ only_bind?: (() => boolean) | undefined; }'.", + "range": { + "end": { + "character": 16, + "line": 22 + }, + "start": { + "character": 8, + "line": 22 + } + }, + "severity": 1, + "source": "ts", + "tags": [] + }, + { + "code": 2353, + "message": "Object literal may only specify known properties, and 'readonly' does not exist in type '{ only_bind?: (() => boolean) | undefined; }'.", + "range": { + "end": { + "character": 20, + "line": 25 + }, + "start": { + "character": 12, + "line": 25 + } + }, + "severity": 1, + "source": "ts", + "tags": [] + } +] diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bindings/input.svelte b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bindings/input.svelte index 1dc072434..55de44f2d 100644 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bindings/input.svelte +++ b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bindings/input.svelte @@ -18,7 +18,7 @@ - + diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/component-invalid/components.d.ts b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/component-invalid/components.d.ts index 174a16d6b..f359fd80a 100644 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/component-invalid/components.d.ts +++ b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/component-invalid/components.d.ts @@ -15,4 +15,6 @@ export class Works3 extends SvelteComponentTyped< { [evt: string]: CustomEvent }, Record > {} +// @ts-ignore doesn't exist in Svelte 4 +export declare const Works4: import('svelte').Component<{ foo: string }>; export class DoesntWork {} diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/component-invalid/expected_svelte_5.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/component-invalid/expected_svelte_5.json new file mode 100644 index 000000000..ba1364156 --- /dev/null +++ b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/component-invalid/expected_svelte_5.json @@ -0,0 +1,57 @@ +[ + { + "range": { + "start": { "line": 19, "character": 1 }, + "end": { "line": 19, "character": 11 } + }, + "severity": 1, + "source": "ts", + "message": "Argument of type 'typeof DoesntWork' is not assignable to parameter of type 'ConstructorOfATypedSvelteComponent | Component | null | undefined'.\n Type 'typeof DoesntWork' is not assignable to type 'ConstructorOfATypedSvelteComponent'.\n Type 'DoesntWork' is missing the following properties from type 'ATypedSvelteComponent': $$prop_def, $$events_def, $$slot_def, $on\n\nPossible causes:\n- You use the instance type of a component where you should use the constructor type\n- Type definitions are missing for this Svelte Component. ", + "code": 2345, + "tags": [] + }, + { + "range": { + "start": { "line": 20, "character": 10 }, + "end": { "line": 20, "character": 25 } + }, + "severity": 1, + "source": "ts", + "message": "Type 'boolean' is not assignable to type 'never'.", + "code": 2322, + "tags": [] + }, + { + "range": { + "start": { "line": 21, "character": 24 }, + "end": { "line": 21, "character": 34 } + }, + "severity": 1, + "source": "ts", + "message": "Argument of type 'typeof DoesntWork' is not assignable to parameter of type 'ConstructorOfATypedSvelteComponent | Component | null | undefined'.\n\nPossible causes:\n- You use the instance type of a component where you should use the constructor type\n- Type definitions are missing for this Svelte Component. ", + "code": 2345, + "tags": [] + }, + { + "range": { + "start": { "line": 24, "character": 1 }, + "end": { "line": 24, "character": 11 } + }, + "severity": 1, + "source": "ts", + "message": "Argument of type 'typeof DoesntWork' is not assignable to parameter of type 'ConstructorOfATypedSvelteComponent | Component | null | undefined'.\n\nPossible causes:\n- You use the instance type of a component where you should use the constructor type\n- Type definitions are missing for this Svelte Component. ", + "code": 2345, + "tags": [] + }, + { + "range": { + "start": { "line": 27, "character": 24 }, + "end": { "line": 27, "character": 34 } + }, + "severity": 1, + "source": "ts", + "message": "Argument of type 'typeof DoesntWork' is not assignable to parameter of type 'ConstructorOfATypedSvelteComponent | Component | null | undefined'.\n\nPossible causes:\n- You use the instance type of a component where you should use the constructor type\n- Type definitions are missing for this Svelte Component. ", + "code": 2345, + "tags": [] + } +] diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/component-invalid/input.svelte b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/component-invalid/input.svelte index ec3eaad79..5d4587af5 100644 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/component-invalid/input.svelte +++ b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/component-invalid/input.svelte @@ -1,6 +1,6 @@ @@ -28,3 +28,7 @@ ''} let:etc> {etc} + + + + diff --git a/packages/svelte2tsx/repl/debug.ts b/packages/svelte2tsx/repl/debug.ts index cc3b646a2..98d49c7d1 100644 --- a/packages/svelte2tsx/repl/debug.ts +++ b/packages/svelte2tsx/repl/debug.ts @@ -2,9 +2,20 @@ import fs from 'fs'; import { svelte2tsx } from '../src/svelte2tsx/index'; import { VERSION } from 'svelte/compiler'; -const content = fs.readFileSync(`${__dirname}/index.svelte`, 'utf-8'); +for (const file of fs.readdirSync(__dirname)) { + // only read if is a file + if (!fs.lstatSync(`${__dirname}/${file}`).isFile() || !file.endsWith('.svelte')) continue; + const content = fs.readFileSync(`${__dirname}/${file}`, 'utf-8'); + const isTsFile = content.includes('lang="ts"'); + const output = svelte2tsx(content, {version: VERSION, filename: file, isTsFile}).code; + fs.writeFileSync(`${__dirname}/output/${file}.${isTsFile ? 'ts' : 'js'}`, output); + console.log(output); +} + +// If you're only interested in the index file: +// const content = fs.readFileSync(`${__dirname}/index.svelte`, 'utf-8'); +// console.log(svelte2tsx(content, {version: VERSION,isTsFile: true}).code); -console.log(svelte2tsx(content, {version: VERSION}).code); /** * To enable the REPL, simply run the "dev" package script. * diff --git a/packages/svelte2tsx/src/emitDts.ts b/packages/svelte2tsx/src/emitDts.ts index 6005c61a4..32d8c2be1 100644 --- a/packages/svelte2tsx/src/emitDts.ts +++ b/packages/svelte2tsx/src/emitDts.ts @@ -243,6 +243,12 @@ interface SvelteMap { async function createSvelteMap(config: EmitDtsConfig): Promise { const svelteFiles = new Map(); + // TODO detect Svelte version in here and set shimsPath accordingly if not given from above + const noSvelteComponentTyped = config.svelteShimsPath + .replace(/\\/g, '/') + .endsWith('svelte2tsx/svelte-shims-v4.d.ts'); + const version = noSvelteComponentTyped ? undefined : '3.42.0'; + function add(path: string): boolean { const code = ts.sys.readFile(path, 'utf-8'); const isTsFile = /]*?lang=('|")(ts|typescript)('|")/.test(code); @@ -250,9 +256,8 @@ async function createSvelteMap(config: EmitDtsConfig): Promise { filename: path, isTsFile, mode: 'dts', - noSvelteComponentTyped: config.svelteShimsPath - .replace(/\\/g, '/') - .endsWith('svelte2tsx/svelte-shims-v4.d.ts') + version, + noSvelteComponentTyped: noSvelteComponentTyped }).code; svelteFiles.set(path, transformed); return isTsFile; diff --git a/packages/svelte2tsx/src/svelte2tsx/addComponentExport.ts b/packages/svelte2tsx/src/svelte2tsx/addComponentExport.ts index fd7c04610..39d14ad4e 100644 --- a/packages/svelte2tsx/src/svelte2tsx/addComponentExport.ts +++ b/packages/svelte2tsx/src/svelte2tsx/addComponentExport.ts @@ -4,6 +4,7 @@ import MagicString from 'magic-string'; import { ExportedNames } from './nodes/ExportedNames'; import { ComponentDocumentation } from './nodes/ComponentDocumentation'; import { Generics } from './nodes/Generics'; +import { surroundWithIgnoreComments } from '../utils/ignore'; export interface AddComponentExportPara { str: MagicString; @@ -21,6 +22,7 @@ export interface AddComponentExportPara { mode: 'ts' | 'dts' | 'tsx'; generics: Generics; usesSlots: boolean; + isSvelte5: boolean; noSvelteComponentTyped?: boolean; } @@ -49,6 +51,7 @@ function addGenericsComponentExport({ str, generics, usesSlots, + isSvelte5, noSvelteComponentTyped }: AddComponentExportPara) { const genericsDef = generics.toDefinitionString(); @@ -72,6 +75,12 @@ class __sveltets_Render${genericsDef} { slots() { return render${genericsRef}().slots; } +${ + isSvelte5 + ? ` bindings() { return ${exportedNames.createBindingsStr()}; } + exports() { return ${exportedNames.hasExports() ? `render${genericsRef}().exports` : '{}'}; } +}` + : '}' } `; @@ -82,19 +91,25 @@ class __sveltets_Render${genericsDef} { const [EventsName] = addTypeExport(str, className, 'Events'); const [SlotsName] = addTypeExport(str, className, 'Slots'); - /** - * In Svelte 5 runes mode we add a custom constructor to override the default one which implicitly makes all properties bindable. - * Remove this once Svelte typings no longer do that (Svelte 6 or 7) - */ - let customConstructor = ''; - if (exportedNames.hasPropsRune()) { - if (!usesSlots) { - customConstructor = `\n constructor(options: import('svelte').ComponentConstructorOptions<${returnType('props')}>) { super(options); }`; - } - customConstructor += exportedNames.createBindingsStr(); - } - - if (mode === 'dts') { + if (isSvelte5) { + // Don't add props/events/slots type exports in dts mode for now, maybe someone asks for it to be back, + // but it's safer to not do it for now to have more flexibility in the future. + const propsType = + !canHaveAnyProp && exportedNames.hasNoProps() + ? `{$$events?: ${returnType('events')}${usesSlots ? `, $$slots?: ${returnType('slots')}, children?: any` : ''}}` + : `${returnType('props')} & {$$events?: ${returnType('events')}${usesSlots ? `, $$slots?: ${returnType('slots')}, children?: any` : ''}}`; + statement += + `\ninterface $$IsomorphicComponent {\n` + + ` new ${genericsDef}(options: import('svelte').ComponentConstructorOptions<${returnType('props') + (usesSlots ? '& {children?: any}' : '')}>): import('svelte').SvelteComponent<${returnType('props')}, ${returnType('events')}, ${returnType('slots')}> & { $$bindings?: ${returnType('bindings')} } & ${returnType('exports')};\n` + + ` ${genericsDef}(internal: unknown, props: ${propsType}): ${returnType('exports')};\n` + + ` z_$$bindings?: ReturnType<__sveltets_Render${generics.toReferencesAnyString()}['bindings']>;\n` + + `}\n` + + `${doc}const ${className || '$$Component'}: $$IsomorphicComponent = null as any;\n` + + surroundWithIgnoreComments( + `type ${className || '$$Component'}${genericsDef} = InstanceType;\n` + ) + + `export default ${className || '$$Component'};`; + } else if (mode === 'dts') { statement += `export type ${PropsName}${genericsDef} = ${returnType('props')};\n` + `export type ${EventsName}${genericsDef} = ${returnType('events')};\n` + @@ -102,7 +117,6 @@ class __sveltets_Render${genericsDef} { `\n${doc}export default class${ className ? ` ${className}` : '' }${genericsDef} extends ${svelteComponentClass}<${PropsName}${genericsRef}, ${EventsName}${genericsRef}, ${SlotsName}${genericsRef}> {` + - customConstructor + exportedNames.createClassGetters(genericsRef) + (usesAccessors ? exportedNames.createClassAccessors() : '') + '\n}'; @@ -114,7 +128,6 @@ class __sveltets_Render${genericsDef} { }${genericsDef} extends __SvelteComponentTyped__<${returnType('props')}, ${returnType( 'events' )}, ${returnType('slots')}> {` + - customConstructor + exportedNames.createClassGetters(genericsRef) + (usesAccessors ? exportedNames.createClassAccessors() : '') + '\n}'; @@ -134,7 +147,8 @@ function addSimpleComponentExport({ usesAccessors, str, usesSlots, - noSvelteComponentTyped + noSvelteComponentTyped, + isSvelte5 }: AddComponentExportPara) { const propDef = props( isTsFile, @@ -146,61 +160,84 @@ function addSimpleComponentExport({ const doc = componentDocumentation.getFormatted(); const className = fileName && classNameFromFilename(fileName, mode !== 'dts'); - /** - * In Svelte 5 runes mode we add a custom constructor to override the default one which implicitly makes all properties bindable. - * Remove this once Svelte typings no longer do that (Svelte 6 or 7) - */ - let customConstructor = ''; - if (exportedNames.hasPropsRune()) { - if (!usesSlots) { - customConstructor = `\n constructor(options = __sveltets_2_runes_constructor(${propDef})) { super(options); }`; - } - customConstructor += exportedNames.createBindingsStr(); - } - let statement: string; - if (mode === 'dts' && isTsFile) { - const svelteComponentClass = noSvelteComponentTyped - ? 'SvelteComponent' - : 'SvelteComponentTyped'; - const [PropsName, PropsExport] = addTypeExport(str, className, 'Props'); - const [EventsName, EventsExport] = addTypeExport(str, className, 'Events'); - const [SlotsName, SlotsExport] = addTypeExport(str, className, 'Slots'); + if (mode === 'dts') { + if (isSvelte5) { + // Inline definitions from Svelte shims; else dts files will reference the globals which will be unresolved + statement = + `\ninterface $$__sveltets_2_IsomorphicComponent = any, Events extends Record = any, Slots extends Record = any, Exports = {}, Bindings = string> { + new (options: import('svelte').ComponentConstructorOptions): import('svelte').SvelteComponent & { $$bindings?: Bindings } & Exports; + (internal: unknown, props: ${!canHaveAnyProp && exportedNames.hasNoProps() ? '{$$events?: Events, $$slots?: Slots}' : 'Props & {$$events?: Events, $$slots?: Slots}'}): Exports; + z_$$bindings?: Bindings; +}\n` + + (usesSlots + ? `type $$__sveltets_2_PropsWithChildren = Props & + (Slots extends { default: any } + ? Props extends Record + ? any + : { children?: any } + : {}); + declare function $$__sveltets_2_isomorphic_component_slots< + Props extends Record, Events extends Record, Slots extends Record, Exports extends Record, Bindings extends string + >(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren, Events, Slots, Exports, Bindings>;\n` + : ` +declare function $$__sveltets_2_isomorphic_component< + Props extends Record, Events extends Record, Slots extends Record, Exports extends Record, Bindings extends string +>(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): $$__sveltets_2_IsomorphicComponent;\n`) + + `${doc}const ${className || '$$Component'} = $$__sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` + + surroundWithIgnoreComments( + `type ${className || '$$Component'} = InstanceType;\n` + ) + + `export default ${className || '$$Component'};`; + } else if (isTsFile) { + const svelteComponentClass = noSvelteComponentTyped + ? 'SvelteComponent' + : 'SvelteComponentTyped'; + const [PropsName, PropsExport] = addTypeExport(str, className, 'Props'); + const [EventsName, EventsExport] = addTypeExport(str, className, 'Events'); + const [SlotsName, SlotsExport] = addTypeExport(str, className, 'Slots'); - statement = - `\nconst __propDef = ${propDef};\n` + - PropsExport + - EventsExport + - SlotsExport + - `\n${doc}export default class${ - className ? ` ${className}` : '' - } extends ${svelteComponentClass}<${PropsName}, ${EventsName}, ${SlotsName}> {` + - customConstructor + - exportedNames.createClassGetters() + - (usesAccessors ? exportedNames.createClassAccessors() : '') + - '\n}'; - } else if (mode === 'dts' && !isTsFile) { - statement = - `\nconst __propDef = ${propDef};\n` + - `/** @typedef {typeof __propDef.props} ${className}Props */\n` + - `/** @typedef {typeof __propDef.events} ${className}Events */\n` + - `/** @typedef {typeof __propDef.slots} ${className}Slots */\n` + - `\n${doc}export default class${ - className ? ` ${className}` : '' - } extends __sveltets_2_createSvelte2TsxComponent(${propDef}) {` + - customConstructor + - exportedNames.createClassGetters() + - (usesAccessors ? exportedNames.createClassAccessors() : '') + - '\n}'; + statement = + `\nconst __propDef = ${propDef};\n` + + PropsExport + + EventsExport + + SlotsExport + + `\n${doc}export default class${ + className ? ` ${className}` : '' + } extends ${svelteComponentClass}<${PropsName}, ${EventsName}, ${SlotsName}> {` + + exportedNames.createClassGetters() + + (usesAccessors ? exportedNames.createClassAccessors() : '') + + '\n}'; + } else { + statement = + `\nconst __propDef = ${propDef};\n` + + `/** @typedef {typeof __propDef.props} ${className}Props */\n` + + `/** @typedef {typeof __propDef.events} ${className}Events */\n` + + `/** @typedef {typeof __propDef.slots} ${className}Slots */\n` + + `\n${doc}export default class${ + className ? ` ${className}` : '' + } extends __sveltets_2_createSvelte2TsxComponent(${propDef}) {` + + exportedNames.createClassGetters() + + (usesAccessors ? exportedNames.createClassAccessors() : '') + + '\n}'; + } } else { - statement = - `\n\n${doc}export default class${ - className ? ` ${className}` : '' - } extends __sveltets_2_createSvelte2TsxComponent(${propDef}) {` + - customConstructor + - exportedNames.createClassGetters() + - (usesAccessors ? exportedNames.createClassAccessors() : '') + - '\n}'; + if (isSvelte5) { + statement = + `\n${doc}const ${className || '$$Component'} = __sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` + + surroundWithIgnoreComments( + `type ${className || '$$Component'} = InstanceType;\n` + ) + + `export default ${className || '$$Component'};`; + } else { + statement = + `\n\n${doc}export default class${ + className ? ` ${className}` : '' + } extends __sveltets_2_createSvelte2TsxComponent(${propDef}) {` + + exportedNames.createClassGetters() + + (usesAccessors ? exportedNames.createClassAccessors() : '') + + '\n}'; + } } str.append(statement); @@ -254,7 +291,9 @@ function props( exportedNames: ExportedNames, renderStr: string ) { - if (isTsFile) { + if (exportedNames.usesRunes()) { + return renderStr; + } else if (isTsFile) { return canHaveAnyProp ? `__sveltets_2_with_any(${renderStr})` : renderStr; } else { const optionalProps = exportedNames.createOptionalPropsArray(); diff --git a/packages/svelte2tsx/src/svelte2tsx/index.ts b/packages/svelte2tsx/src/svelte2tsx/index.ts index 96d8f91b8..e6410d661 100644 --- a/packages/svelte2tsx/src/svelte2tsx/index.ts +++ b/packages/svelte2tsx/src/svelte2tsx/index.ts @@ -370,7 +370,7 @@ 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); + let exportedNames = new ExportedNames(str, 0, basename, options?.isTsFile, svelte5Plus); let generics = new Generics(str, 0, { attributes: [] } as any); let uses$$SlotsInterface = false; if (scriptTag) { @@ -386,7 +386,8 @@ export function svelte2tsx( options.mode, /**hasModuleScripts */ !!moduleScriptTag, options?.isTsFile, - basename + basename, + svelte5Plus ); uses$$props = uses$$props || res.uses$$props; uses$$restProps = uses$$restProps || res.uses$$restProps; @@ -395,6 +396,7 @@ export function svelte2tsx( ({ exportedNames, events, generics, uses$$SlotsInterface } = res); } + exportedNames.usesAccessors = usesAccessors; if (svelte5Plus) { exportedNames.checkGlobalsForRunes(implicitStoreValues.getGlobals()); } @@ -433,7 +435,7 @@ export function svelte2tsx( addComponentExport({ str, canHaveAnyProp: !exportedNames.uses$$Props && (uses$$props || uses$$restProps), - strictEvents: events.hasStrictEvents(), + strictEvents: events.hasStrictEvents(), // TODO in Svelte 6 we should also apply strictEvents in runes mode isTsFile: options?.isTsFile, exportedNames, usesAccessors, @@ -442,6 +444,7 @@ export function svelte2tsx( componentDocumentation, mode: options.mode, generics, + isSvelte5: svelte5Plus, noSvelteComponentTyped: options.noSvelteComponentTyped }); diff --git a/packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts b/packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts index 7417cfcb2..e4a634b27 100644 --- a/packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts +++ b/packages/svelte2tsx/src/svelte2tsx/nodes/ExportedNames.ts @@ -20,6 +20,7 @@ interface ExportedName { } export class ExportedNames { + public usesAccessors = false; /** * Uses the `$$Props` type */ @@ -52,7 +53,8 @@ export class ExportedNames { private str: MagicString, private astOffset: number, private basename: string, - private isTsFile: boolean + private isTsFile: boolean, + private isSvelte5Plus: boolean ) {} handleVariableStatement(node: ts.VariableStatement, parent: ts.Node): void { @@ -622,15 +624,15 @@ export class ExportedNames { createPropsStr(uses$$propsOr$$restProps: boolean): string { const names = Array.from(this.exports.entries()); - if (this.$props.type) { - return '{} as any as ' + this.$props.type; - } + if (this.usesRunes()) { + if (this.$props.type) { + return '{} as any as ' + this.$props.type; + } - if (this.$props.comment) { - return this.$props.comment + '({})'; - } + if (this.$props.comment) { + return this.$props.comment + '({})'; + } - if (this.usesRunes()) { // Necessary, because {} roughly equals to any return this.isTsFile ? '{} as Record' @@ -679,29 +681,57 @@ export class ExportedNames { return `{${returnElements.join(' , ')}} as {${returnElementsType.join(', ')}}`; } + hasNoProps() { + if (this.usesRunes()) { + return !this.$props.type && !this.$props.comment; + } + + const names = Array.from(this.exports.entries()); + return names.length === 0; + } + createBindingsStr(): string { - // will be just the empty strings for zero bindings, which is impossible to create a binding for, so it works out fine - return `\n $$bindings = __sveltets_$$bindings('${this.$props.bindings.join("', '")}');`; + if (this.usesRunes()) { + // will be just the empty strings for zero bindings, which is impossible to create a binding for, so it works out fine + return `__sveltets_$$bindings('${this.$props.bindings.join("', '")}')`; + } else { + return '""'; + } } /** * In runes mode, exports are no longer part of props because you cannot `bind:` to them, - * which is why we need a separate return type for them. + * which is why we need a separate return type for them. In Svelte 5, the isomorphic component + * needs them separate, too. */ createExportsStr(): string { const names = Array.from(this.exports.entries()); const others = names.filter(([, { isLet }]) => !isLet); + const needsAccessors = this.usesAccessors && names.length > 0 && !this.usesRunes(); // runes mode doesn't support accessors + + if (this.isSvelte5Plus && (others.length > 0 || this.usesRunes() || needsAccessors)) { + let str = ''; + + if (others.length > 0 || needsAccessors) { + if (this.isTsFile) { + str += + ', exports: {} as any as { ' + + this.createReturnElementsType( + needsAccessors ? names : others, + undefined, + true + ).join(',') + + ' }'; + } else { + str += `, exports: /** @type {{${this.createReturnElementsType(needsAccessors ? names : others, false, true)}}} */ ({})`; + } + } - if (this.usesRunes() && others.length > 0) { - if (this.isTsFile) { - return ( - ', exports: {} as any as { ' + - this.createReturnElementsType(others, undefined, true).join(',') + - ' }' - ); - } else { - return `, exports: /** @type {${this.createReturnElementsType(others, false, true)}} */ ({})`; + if (this.usesRunes()) { + str += `, bindings: ${this.createBindingsStr()}`; } + + return str; } return ''; @@ -750,16 +780,22 @@ export class ExportedNames { return this.exports; } + hasExports(): boolean { + const names = Array.from(this.exports.entries()); + return this.usesAccessors ? names.length > 0 : names.some(([, { isLet }]) => !isLet); + } + hasPropsRune() { - return this.$props.type || this.$props.comment; + return this.isSvelte5Plus && (this.$props.type || this.$props.comment); } checkGlobalsForRunes(globals: string[]) { const runes = ['$state', '$derived', '$effect']; // no need to check for props, already handled through other means in here - this.hasRunesGlobals = globals.some((global) => runes.includes(global)); + this.hasRunesGlobals = + this.isSvelte5Plus && globals.some((global) => runes.includes(global)); } - private usesRunes() { + usesRunes() { return this.hasRunesGlobals || this.hasPropsRune(); } } diff --git a/packages/svelte2tsx/src/svelte2tsx/nodes/Generics.ts b/packages/svelte2tsx/src/svelte2tsx/nodes/Generics.ts index 136be5099..79d1918a4 100644 --- a/packages/svelte2tsx/src/svelte2tsx/nodes/Generics.ts +++ b/packages/svelte2tsx/src/svelte2tsx/nodes/Generics.ts @@ -102,6 +102,10 @@ export class Generics { return this.references.length ? `<${this.references.join(',')}>` : ''; } + toReferencesAnyString() { + return this.references.length ? `<${this.references.map(() => 'any').join(',')}>` : ''; + } + has() { return this.definitions.length > 0; } diff --git a/packages/svelte2tsx/src/svelte2tsx/processInstanceScriptContent.ts b/packages/svelte2tsx/src/svelte2tsx/processInstanceScriptContent.ts index c25bf8699..a3eaad0e8 100644 --- a/packages/svelte2tsx/src/svelte2tsx/processInstanceScriptContent.ts +++ b/packages/svelte2tsx/src/svelte2tsx/processInstanceScriptContent.ts @@ -41,7 +41,8 @@ export function processInstanceScriptContent( mode: 'ts' | 'dts', hasModuleScript: boolean, isTSFile: boolean, - basename: string + basename: string, + isSvelte5Plus: boolean ): InstanceScriptProcessResult { const htmlx = str.original; const scriptContent = htmlx.substring(script.content.start, script.content.end); @@ -53,7 +54,7 @@ export function processInstanceScriptContent( ts.ScriptKind.TS ); const astOffset = script.content.start; - const exportedNames = new ExportedNames(str, astOffset, basename, isTSFile); + const exportedNames = new ExportedNames(str, astOffset, basename, isTSFile, isSvelte5Plus); const generics = new Generics(str, astOffset, script); const interfacesAndTypes = new InterfacesAndTypes(); diff --git a/packages/svelte2tsx/svelte-shims-v4.d.ts b/packages/svelte2tsx/svelte-shims-v4.d.ts index e83032bc7..9ea027599 100644 --- a/packages/svelte2tsx/svelte-shims-v4.d.ts +++ b/packages/svelte2tsx/svelte-shims-v4.d.ts @@ -70,30 +70,30 @@ declare function __sveltets_2_slotsType(slots: S // An empty array of optionalProps makes OptionalProps type any, which means we lose the prop typing. // optionalProps need to be first or its type cannot be infered correctly. -declare function __sveltets_2_partial( - render: {props: Props, events: Events, slots: Slots } -): {props: Expand>, events: Events, slots: Expand> } -declare function __sveltets_2_partial( +declare function __sveltets_2_partial( + render: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings } +): {props: Expand>, events: Events, slots: Expand>, exports?: Exports, bindings?: Bindings } +declare function __sveltets_2_partial( optionalProps: OptionalProps[], - render: {props: Props, events: Events, slots: Slots } -): {props: Expand, OptionalProps>>, events: Events, slots: Expand> } + render: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings } +): {props: Expand, OptionalProps>>, events: Events, slots: Expand>, exports?: Exports, bindings?: Bindings } -declare function __sveltets_2_partial_with_any( - render: {props: Props, events: Events, slots: Slots } -): {props: Expand & SvelteAllProps>, events: Events, slots: Expand> } -declare function __sveltets_2_partial_with_any( +declare function __sveltets_2_partial_with_any( + render: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings } +): {props: Expand & SvelteAllProps>, events: Events, slots: Expand>, exports?: Exports, bindings?: Bindings } +declare function __sveltets_2_partial_with_any( optionalProps: OptionalProps[], - render: {props: Props, events: Events, slots: Slots } -): {props: Expand, OptionalProps> & SvelteAllProps>, events: Events, slots: Expand> } + render: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings } +): {props: Expand, OptionalProps> & SvelteAllProps>, events: Events, slots: Expand>, exports?: Exports, bindings?: Bindings } -declare function __sveltets_2_with_any( - render: {props: Props, events: Events, slots: Slots } -): {props: Expand, events: Events, slots: Slots } +declare function __sveltets_2_with_any( + render: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings } +): {props: Expand, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings } -declare function __sveltets_2_with_any_event( - render: {props: Props, events: Events, slots: Slots } -): {props: Props, events: Events & {[evt: string]: CustomEvent;}, slots: Slots } +declare function __sveltets_2_with_any_event( + render: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings } +): {props: Props, events: Events & {[evt: string]: CustomEvent;}, slots: Slots, exports?: Exports, bindings?: Bindings } declare function __sveltets_2_store_get(store: SvelteStore): T declare function __sveltets_2_store_get | undefined | null>(store: Store): Store extends SvelteStore ? T : Store; @@ -225,8 +225,11 @@ declare type ATypedSvelteComponent = { * ``` */ declare type ConstructorOfATypedSvelteComponent = new (args: {target: any, props?: any}) => ATypedSvelteComponent -declare function __sveltets_2_ensureComponent(type: T): NonNullable; - +declare function __sveltets_2_ensureComponent< + // @ts-ignore svelte.Component doesn't exist in Svelte 4 + T extends ConstructorOfATypedSvelteComponent | (0 extends (1 & import('svelte').Component) ? never : import('svelte').Component) | null | undefined + // @ts-ignore svelte.Component doesn't exist in Svelte 4 +>(type: T): NonNullable ? typeof import('svelte').SvelteComponent : T>; declare function __sveltets_2_ensureArray | Iterable>(array: T): T extends ArrayLike ? U[] : T extends Iterable ? Iterable : any[]; type __sveltets_2_PropsWithChildren = Props & @@ -241,3 +244,17 @@ type __sveltets_2_PropsWithChildren = Props & declare function __sveltets_2_runes_constructor(render: {props: Props }): import("svelte").ComponentConstructorOptions; declare function __sveltets_$$bindings(...bindings: Bindings): Bindings[number]; + +interface __sveltets_2_IsomorphicComponent = any, Events extends Record = any, Slots extends Record = any, Exports = {}, Bindings = string> { + new (options: import('svelte').ComponentConstructorOptions): import('svelte').SvelteComponent & { $$bindings?: Bindings } & Exports; + (internal: unknown, props: Props extends Record ? {$$events?: Events, $$slots?: Slots} : Props & {$$events?: Events, $$slots?: Slots}): Exports; + z_$$bindings?: Bindings; +} + +declare function __sveltets_2_isomorphic_component< + Props extends Record, Events extends Record, Slots extends Record, Exports extends Record, Bindings extends string +>(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): __sveltets_2_IsomorphicComponent; + +declare function __sveltets_2_isomorphic_component_slots< + Props extends Record, Events extends Record, Slots extends Record, Exports extends Record, Bindings extends string +>(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): __sveltets_2_IsomorphicComponent<__sveltets_2_PropsWithChildren, Events, Slots, Exports, Bindings>; diff --git a/packages/svelte2tsx/test/emitDts/samples/javascript-runes.v5/expected/TestRunes.svelte.d.ts b/packages/svelte2tsx/test/emitDts/samples/javascript-runes.v5/expected/TestRunes.svelte.d.ts new file mode 100644 index 000000000..220b4fdad --- /dev/null +++ b/packages/svelte2tsx/test/emitDts/samples/javascript-runes.v5/expected/TestRunes.svelte.d.ts @@ -0,0 +1,21 @@ +/// +interface $$__sveltets_2_IsomorphicComponent = any, Events extends Record = any, Slots extends Record = any, Exports = {}, Bindings = string> { + new (options: import('svelte').ComponentConstructorOptions): import('svelte').SvelteComponent & { + $$bindings?: Bindings; + } & Exports; + (internal: unknown, props: Props & { + $$events?: Events; + $$slots?: Slots; + }): Exports; + z_$$bindings?: Bindings; +} +declare const TestRunes: $$__sveltets_2_IsomorphicComponent<{ + foo: string; + bar?: number; +}, { + [evt: string]: CustomEvent; +}, {}, { + baz: () => void; +}, "bar">; +type TestRunes = InstanceType; +export default TestRunes; diff --git a/packages/svelte2tsx/test/emitDts/samples/javascript-runes.v5/jsconfig.json b/packages/svelte2tsx/test/emitDts/samples/javascript-runes.v5/jsconfig.json new file mode 100644 index 000000000..edbf12661 --- /dev/null +++ b/packages/svelte2tsx/test/emitDts/samples/javascript-runes.v5/jsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "checkJs": true + }, + "include": ["./src/**/*.d.ts", "./src/**/*.js", "./src/**/*.ts", "./src/**/*.svelte"] +} diff --git a/packages/svelte2tsx/test/emitDts/samples/javascript-runes.v5/src/TestRunes.svelte b/packages/svelte2tsx/test/emitDts/samples/javascript-runes.v5/src/TestRunes.svelte new file mode 100644 index 000000000..cd9f8382b --- /dev/null +++ b/packages/svelte2tsx/test/emitDts/samples/javascript-runes.v5/src/TestRunes.svelte @@ -0,0 +1,5 @@ + diff --git a/packages/svelte2tsx/test/emitDts/samples/typescript-runes-generics.v5/expected/TestRunes.svelte.d.ts b/packages/svelte2tsx/test/emitDts/samples/typescript-runes-generics.v5/expected/TestRunes.svelte.d.ts new file mode 100644 index 000000000..ffa7cdda2 --- /dev/null +++ b/packages/svelte2tsx/test/emitDts/samples/typescript-runes-generics.v5/expected/TestRunes.svelte.d.ts @@ -0,0 +1,27 @@ +/// +declare class __sveltets_Render, K extends keyof T> { + props(): { + foo: T; + bar?: K; + }; + events(): {} & { + [evt: string]: CustomEvent; + }; + slots(): {}; + bindings(): "bar"; + exports(): { + baz: () => T; + }; +} +interface $$IsomorphicComponent { + new , K extends keyof T>(options: import('svelte').ComponentConstructorOptions['props']>>): import('svelte').SvelteComponent['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> & { + $$bindings?: ReturnType<__sveltets_Render['bindings']>; + } & ReturnType<__sveltets_Render['exports']>; + , K extends keyof T>(internal: unknown, props: ReturnType<__sveltets_Render['props']> & { + $$events?: ReturnType<__sveltets_Render['events']>; + }): ReturnType<__sveltets_Render['exports']>; + z_$$bindings?: ReturnType<__sveltets_Render['bindings']>; +} +declare const TestRunes: $$IsomorphicComponent; +type TestRunes, K extends keyof T> = InstanceType>; +export default TestRunes; diff --git a/packages/svelte2tsx/test/emitDts/samples/typescript-runes-generics.v5/src/TestRunes.svelte b/packages/svelte2tsx/test/emitDts/samples/typescript-runes-generics.v5/src/TestRunes.svelte new file mode 100644 index 000000000..0587c48df --- /dev/null +++ b/packages/svelte2tsx/test/emitDts/samples/typescript-runes-generics.v5/src/TestRunes.svelte @@ -0,0 +1,5 @@ + diff --git a/packages/svelte2tsx/test/emitDts/samples/typescript-runes-generics.v5/tsconfig.json b/packages/svelte2tsx/test/emitDts/samples/typescript-runes-generics.v5/tsconfig.json new file mode 100644 index 000000000..5b465a5c9 --- /dev/null +++ b/packages/svelte2tsx/test/emitDts/samples/typescript-runes-generics.v5/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "moduleResolution": "node", + "module": "es2020", + "lib": ["es2020", "DOM"], + "target": "es2019", + "isolatedModules": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "allowJs": true, + "checkJs": true + }, + "include": ["./src/**/*.d.ts", "./src/**/*.js", "./src/**/*.ts", "./src/**/*.svelte"] +} diff --git a/packages/svelte2tsx/test/emitDts/samples/typescript-runes.v5/expected/TestRunes.svelte.d.ts b/packages/svelte2tsx/test/emitDts/samples/typescript-runes.v5/expected/TestRunes.svelte.d.ts index e13bde503..220b4fdad 100644 --- a/packages/svelte2tsx/test/emitDts/samples/typescript-runes.v5/expected/TestRunes.svelte.d.ts +++ b/packages/svelte2tsx/test/emitDts/samples/typescript-runes.v5/expected/TestRunes.svelte.d.ts @@ -1,23 +1,21 @@ -import { SvelteComponent } from "svelte"; -declare const __propDef: { - props: { - foo: string; - bar?: number; - }; - events: { - [evt: string]: CustomEvent; - }; - slots: {}; -}; -export type TestRunesProps = typeof __propDef.props; -export type TestRunesEvents = typeof __propDef.events; -export type TestRunesSlots = typeof __propDef.slots; -export default class TestRunes extends SvelteComponent { - constructor(options?: import("svelte").ComponentConstructorOptions<{ - foo: string; - bar?: number; - }>); - $$bindings: "bar"; - get baz(): () => void; +/// +interface $$__sveltets_2_IsomorphicComponent = any, Events extends Record = any, Slots extends Record = any, Exports = {}, Bindings = string> { + new (options: import('svelte').ComponentConstructorOptions): import('svelte').SvelteComponent & { + $$bindings?: Bindings; + } & Exports; + (internal: unknown, props: Props & { + $$events?: Events; + $$slots?: Slots; + }): Exports; + z_$$bindings?: Bindings; } -export {}; +declare const TestRunes: $$__sveltets_2_IsomorphicComponent<{ + foo: string; + bar?: number; +}, { + [evt: string]: CustomEvent; +}, {}, { + baz: () => void; +}, "bar">; +type TestRunes = InstanceType; +export default TestRunes; diff --git a/packages/svelte2tsx/test/helpers.ts b/packages/svelte2tsx/test/helpers.ts index 26e8ebb68..b3ca7151c 100644 --- a/packages/svelte2tsx/test/helpers.ts +++ b/packages/svelte2tsx/test/helpers.ts @@ -311,19 +311,40 @@ export function test_samples(dir: string, transform: TransformSampleFn, js: 'js' sample.eval('expected.js', output); } - assert.strictEqual( - normalize(transform(input, config).code), - sample.get( - // Check the expectedv2 file first even in Svelte 5 mode because many are identical between versions. - // This way we don't need to duplicate a bunch of expected files. - isSvelte5Plus - ? sample.has(expectedFile) - ? expectedFile - : `expectedv2.${js}` - : expectedFile - ), - TestError.WrongExpected - ); + if (isSvelte5Plus) { + const actual = normalize(transform(input, config).code); + if (sample.has(expectedFile)) { + assert.strictEqual(actual, sample.get(expectedFile), TestError.WrongExpected); + } else { + const expected = sample.get(`expectedv2.${js}`); + try { + assert.strictEqual(actual, expected, TestError.WrongExpected); + } catch (e) { + // retry with the last part (the returned default export) stripped because it's always differing between old and new, + // and if that fails then we're going to rethrow the original error + const expectedModified = expected.substring( + 0, + expected.lastIndexOf('\n\nexport default class') + ); + const actualModified = actual.substring(0, actual.lastIndexOf('\nconst ')); + try { + assert.strictEqual( + actualModified, + expectedModified, + TestError.WrongExpected + ); + } catch (_) { + throw e; + } + } + } + } else { + assert.strictEqual( + normalize(transform(input, config).code), + sample.get(expectedFile), + TestError.WrongExpected + ); + } }); } } diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/accessors-config/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/accessors-config/expected-svelte5.ts new file mode 100644 index 000000000..31eb1069f --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/accessors-config/expected-svelte5.ts @@ -0,0 +1,10 @@ +/// +;function render() { + + let foo: number = undefined/*Ωignore_startΩ*/;foo = __sveltets_2_any(foo);/*Ωignore_endΩ*/; +; +async () => {}; +return { props: {foo: foo}, exports: /** @type {{foo: number}} */ ({}), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(['foo'], __sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-default-slot/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-default-slot/expected-svelte5.ts deleted file mode 100644 index 7de17919e..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/component-default-slot/expected-svelte5.ts +++ /dev/null @@ -1,14 +0,0 @@ -/// -;function render() { - - let b = 7; - -/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/; -async () => { - { svelteHTML.createElement("div", {}); - { __sveltets_createSlot("default", { "a":b,}); } - }}; -return { props: /** @type {Record} */ ({}), slots: {'default': {a:b}}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-multiple-slots/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-multiple-slots/expected-svelte5.ts deleted file mode 100644 index a5d9e5ecd..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/component-multiple-slots/expected-svelte5.ts +++ /dev/null @@ -1,18 +0,0 @@ -/// -;function render() { - - let b = 7; - let d = 5; - let e = 5; - -/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/; -async () => { - { svelteHTML.createElement("div", {}); - { __sveltets_createSlot("default", { "a":b,}); } - { __sveltets_createSlot("test", { "c":d,e,}); } - { __sveltets_createSlot("abc-cde.113", { }); } - }}; -return { props: /** @type {Record} */ ({}), slots: {'default': {a:b}, 'test': {c:d, e:e}, 'abc-cde.113': {}}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-$$slot-interface/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-$$slot-interface/expected-svelte5.ts deleted file mode 100644 index 789a12e41..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-$$slot-interface/expected-svelte5.ts +++ /dev/null @@ -1,24 +0,0 @@ -/// -;function render() { - - interface $$Slots { - default: { - a: number; - }, - foo: { - b: number - } - } - let b = 7; - -/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot<$$Slots>();/*Ωignore_endΩ*/; -async () => { - - { svelteHTML.createElement("div", {}); - { __sveltets_createSlot("default", { "a":b,});} - { __sveltets_createSlot("foo", { b,});} - }}; -return { props: /** @type {Record} */ ({}), slots: {} as unknown as $$Slots, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-$$slot-type/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-$$slot-type/expected-svelte5.ts deleted file mode 100644 index 7a38b740b..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-$$slot-type/expected-svelte5.ts +++ /dev/null @@ -1,24 +0,0 @@ -/// -;function render() { - - type $$Slots = { - default: { - a: number; - }, - foo: { - b: number - } - } - let b = 7; - -/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot<$$Slots>();/*Ωignore_endΩ*/; -async () => { - - { svelteHTML.createElement("div", {}); - { __sveltets_createSlot("default", { "a":b,});} - { __sveltets_createSlot("foo", { b,});} - }}; -return { props: /** @type {Record} */ ({}), slots: {} as unknown as $$Slots, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-crazy-attributes/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-crazy-attributes/expected-svelte5.ts deleted file mode 100644 index 21f09978a..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-crazy-attributes/expected-svelte5.ts +++ /dev/null @@ -1,14 +0,0 @@ -/// -;function render() { - - let b = 7; - -/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/; -async () => { - { svelteHTML.createElement("div", {}); - { __sveltets_createSlot("default", { "a":b,b,"c":`b`,"d":`a${b}`,"e":b,}); } - }}; -return { props: /** @type {Record} */ ({}), slots: {'default': {a:b, b:b, c:"b", d:"__svelte_ts_string", e:b}}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-fallback/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-fallback/expected-svelte5.ts deleted file mode 100644 index 6c64bcd30..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-fallback/expected-svelte5.ts +++ /dev/null @@ -1,11 +0,0 @@ -/// -;function render() { -/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/ -async () => { { __sveltets_createSlot("default", {}); { svelteHTML.createElement("div", {}); } } - { __sveltets_createSlot("foo", { bar,"baz":`boo`,}); - { svelteHTML.createElement("p", {}); } - }}; -return { props: /** @type {Record} */ ({}), slots: {'default': {}, 'foo': {bar:bar, baz:"boo"}}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-forward-with-props/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-forward-with-props/expected-svelte5.ts index 24cabc77c..1dd1dc382 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-forward-with-props/expected-svelte5.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-forward-with-props/expected-svelte5.ts @@ -5,6 +5,6 @@ async () => { { const $$_tneraP0C = __sveltets_2_ensureComponent(Parent); const { __sveltets_createSlot("default", { foo,});} }Parent}}; return { props: /** @type {Record} */ ({}), slots: {'default': {foo:__sveltets_2_instanceOf(Parent).$$slot_def['default'].foo}}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component_slots(__sveltets_2_partial(__sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-inside-await/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-inside-await/expected-svelte5.ts deleted file mode 100644 index f39f92955..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-inside-await/expected-svelte5.ts +++ /dev/null @@ -1,15 +0,0 @@ -/// -;function render() { -/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/ -async () => { { try { const $$_value = await (promise);{ const value = $$_value; - { __sveltets_createSlot("default", { "a":value,}); } -}} catch($$_e) { const err = __sveltets_2_any(); - { __sveltets_createSlot("err", { "err":err,}); } -}} - { const $$_value = await (promise2);{ const { b } = $$_value; - { __sveltets_createSlot("second", { "a":b,}); } -}}}; -return { props: /** @type {Record} */ ({}), slots: {'default': {a:__sveltets_2_unwrapPromiseLike(promise)}, 'err': {err:__sveltets_2_any({})}, 'second': {a:(({ b }) => b)(__sveltets_2_unwrapPromiseLike(promise2))}}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-inside-each/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-inside-each/expected-svelte5.ts deleted file mode 100644 index 89e345d6d..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-inside-each/expected-svelte5.ts +++ /dev/null @@ -1,13 +0,0 @@ -/// -;function render() { -/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/ -async () => { for(let item of __sveltets_2_ensureArray(items)){ - { __sveltets_createSlot("default", { "a":item,}); } -} - for(let { a } of __sveltets_2_ensureArray(items2)){ - { __sveltets_createSlot("second", { a,}); } -}}; -return { props: /** @type {Record} */ ({}), slots: {'default': {a:__sveltets_2_unwrapArr(items)}, 'second': {a:(({ a }) => a)(__sveltets_2_unwrapArr(items2))}}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-let-forward-named-slot/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-let-forward-named-slot/expected-svelte5.ts deleted file mode 100644 index 375b54fff..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-let-forward-named-slot/expected-svelte5.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// -;function render() { -/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/ -async () => { { const $$_tnenopmoC0C = __sveltets_2_ensureComponent(Component); const $$_tnenopmoC0 = new $$_tnenopmoC0C({ target: __sveltets_2_any(), props: {}}); - {const {/*Ωignore_startΩ*/$$_$$/*Ωignore_endΩ*/,a,} = $$_tnenopmoC0.$$slot_def["b"];$$_$$;{ svelteHTML.createElement("div", { }); - { __sveltets_createSlot("default", {a,}); } - }} - Component}}; -return { props: /** @type {Record} */ ({}), slots: {'default': {a:__sveltets_2_instanceOf(Component).$$slot_def['b'].a}}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-let-forward/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-let-forward/expected-svelte5.ts index 2366c31de..fbfdd8b5e 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-let-forward/expected-svelte5.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-let-forward/expected-svelte5.ts @@ -5,6 +5,6 @@ async () => { { const $$_tnenopmoC0C = __sveltets_2_ensureComponent(Component); { __sveltets_createSlot("default", { n,thing,bla,});} }Component}}; return { props: /** @type {Record} */ ({}), slots: {'default': {n:__sveltets_2_instanceOf(Component).$$slot_def['default'].name, thing:__sveltets_2_instanceOf(Component).$$slot_def['default'].thing, bla:(({ bla }) => bla)(__sveltets_2_instanceOf(Component).$$slot_def['default'].whatever)}}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component_slots(__sveltets_2_partial(__sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-nest-scope/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-nest-scope/expected-svelte5.ts index f5b94f0be..8ef850f64 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-nest-scope/expected-svelte5.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-nest-scope/expected-svelte5.ts @@ -13,6 +13,6 @@ async () => { for(let item of __sveltets_2_ensureArray(items)){ }} { __sveltets_createSlot("third", { d,c,}); }}; return { props: /** @type {Record} */ ({}), slots: {'default': {a:(({ a }) => a)(__sveltets_2_unwrapArr(__sveltets_2_unwrapArr(items)))}, 'second': {a:a}, 'third': {d:d, c:c}}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component_slots(__sveltets_2_partial(__sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-no-space/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-no-space/expected-svelte5.ts index e105b7c9b..b2d1ff3bd 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-no-space/expected-svelte5.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-no-space/expected-svelte5.ts @@ -9,6 +9,6 @@ async () => { { svelteHTML.createElement("div", {}); { const $$_tseT1C = __sveltets_2_ensureComponent(Test); const $$_tseT1 = new $$_tseT1C({ target: __sveltets_2_any(), props: { children:() => { return __sveltets_2_any(0); },}});{const {/*Ωignore_startΩ*/$$_$$/*Ωignore_endΩ*/,t,} = $$_tseT1.$$slot_def.default;$$_$$; }Test} }}; return { props: /** @type {Record} */ ({}), slots: {}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(__sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-object-key/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-object-key/expected-svelte5.ts deleted file mode 100644 index 9ae7a6d5e..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-object-key/expected-svelte5.ts +++ /dev/null @@ -1,10 +0,0 @@ -/// -;function render() { -/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/ -async () => { for(let item of __sveltets_2_ensureArray(items)){ - { __sveltets_createSlot("default", { "a":item,"b":{ item },"c":{ item: 'abc' }.item,"d":{ item: item },"e":$item,"f":$item,...g,...item,}); } -}}; -return { props: /** @type {Record} */ ({}), slots: {'default': {a:__sveltets_2_unwrapArr(items), b:{ item:__sveltets_2_unwrapArr(items) }, c:{ item: 'abc' }.item, d:{ item: __sveltets_2_unwrapArr(items) }, e:$item, f:$item, ...g, ...__sveltets_2_unwrapArr(items)}}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-var-shadowing/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-var-shadowing/expected-svelte5.ts deleted file mode 100644 index 2e6a37ea0..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/component-slot-var-shadowing/expected-svelte5.ts +++ /dev/null @@ -1,10 +0,0 @@ -/// -;function render() { -/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/ -async () => { { const $$_each = __sveltets_2_ensureArray(items); for(let items of $$_each){ - { __sveltets_createSlot("default", { "a":items,}); } -}}}; -return { props: /** @type {Record} */ ({}), slots: {'default': {a:__sveltets_2_unwrapArr(items)}}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-with-documentation/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-with-documentation/expected-svelte5.ts new file mode 100644 index 000000000..713794425 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/component-with-documentation/expected-svelte5.ts @@ -0,0 +1,10 @@ +/// +;function render() { +async () => { + + { svelteHTML.createElement("main", {}); }}; +return { props: /** @type {Record} */ ({}), slots: {}, events: {} }} +/** This component does nothing at all */ +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(__sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-with-indented-multiline-documentation/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-with-indented-multiline-documentation/expected-svelte5.ts new file mode 100644 index 000000000..e9ca7546a --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/component-with-indented-multiline-documentation/expected-svelte5.ts @@ -0,0 +1,22 @@ +/// +;function render() { +async () => { + + { svelteHTML.createElement("main", {}); }}; +return { props: /** @type {Record} */ ({}), slots: {}, events: {} }} +/** + * This component has indented multiline documentation: + * + * ```typescript + * type Type = 'type' + * ``` + * + * An indented list: + * - One item + * - Two items + * + * The output should be indented properly! + */ +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(__sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/component-with-multiline-documentation/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/component-with-multiline-documentation/expected-svelte5.ts new file mode 100644 index 000000000..9ebd43fa9 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/component-with-multiline-documentation/expected-svelte5.ts @@ -0,0 +1,16 @@ +/// +;function render() { +async () => { + + { svelteHTML.createElement("main", {}); }}; +return { props: /** @type {Record} */ ({}), slots: {}, events: {} }} +/** + * This component has multiline documentation: + * + * ```typescript + * type Type = 'type' + * ``` + */ +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(__sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/const-tag-component/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/const-tag-component/expected-svelte5.ts index ebfc034c1..4940d69e8 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/const-tag-component/expected-svelte5.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/const-tag-component/expected-svelte5.ts @@ -64,6 +64,6 @@ async () => { { svelteHTML.createElement("div", {});area; volume; perimeter; _width; _height; sum; } }Component}}; return { props: {box: box , constant: constant}, slots: {}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(['box','constant'], __sveltets_2_with_any_event(render()))) { -} \ No newline at end of file +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(['box','constant'], __sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/creates-dts/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/creates-dts/expected-svelte5.ts index 2e9555499..401128e94 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/creates-dts/expected-svelte5.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/creates-dts/expected-svelte5.ts @@ -24,10 +24,20 @@ async () => { { __sveltets_createSlot("default", {bar,}); }}; return { props: { /** @type {boolean} */bar: bar , foobar: foobar}, slots: {'default': {bar:bar}}, events: {'click':__sveltets_2_mapElementEvent('click'), 'hi': __sveltets_2_customEvent} }} -const __propDef = __sveltets_2_partial(['foobar'], __sveltets_2_with_any_event(render())); -/** @typedef {typeof __propDef.props} InputProps */ -/** @typedef {typeof __propDef.events} InputEvents */ -/** @typedef {typeof __propDef.slots} InputSlots */ - -export default class Input extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(['foobar'], __sveltets_2_with_any_event(render()))) { -} \ No newline at end of file +interface $$__sveltets_2_IsomorphicComponent = any, Events extends Record = any, Slots extends Record = any, Exports = {}, Bindings = string> { + new (options: import('svelte').ComponentConstructorOptions): import('svelte').SvelteComponent & { $$bindings?: Bindings } & Exports; + (internal: unknown, props: Props & {$$events?: Events, $$slots?: Slots}): Exports; + z_$$bindings?: Bindings; +} +type $$__sveltets_2_PropsWithChildren = Props & + (Slots extends { default: any } + ? Props extends Record + ? any + : { children?: any } + : {}); + declare function $$__sveltets_2_isomorphic_component_slots< + Props extends Record, Events extends Record, Slots extends Record, Exports extends Record, Bindings extends string + >(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren, Events, Slots, Exports, Bindings>; +const Input = $$__sveltets_2_isomorphic_component_slots(__sveltets_2_partial(['foobar'], __sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input = InstanceType; +/*Ωignore_endΩ*/export default Input; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/creates-no-script-dts/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/creates-no-script-dts/expected-svelte5.ts index b56477b6c..bf5f7c673 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/creates-no-script-dts/expected-svelte5.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/creates-no-script-dts/expected-svelte5.ts @@ -6,10 +6,20 @@ async () => { { svelteHTML.createElement("button", { "on:click":undefined,}); { n; }}}; return { props: /** @type {Record} */ ({}), slots: {'default': {}}, events: {'click':__sveltets_2_mapElementEvent('click')} }} -const __propDef = __sveltets_2_partial(__sveltets_2_with_any_event(render())); -/** @typedef {typeof __propDef.props} InputProps */ -/** @typedef {typeof __propDef.events} InputEvents */ -/** @typedef {typeof __propDef.slots} InputSlots */ - -export default class Input extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file +interface $$__sveltets_2_IsomorphicComponent = any, Events extends Record = any, Slots extends Record = any, Exports = {}, Bindings = string> { + new (options: import('svelte').ComponentConstructorOptions): import('svelte').SvelteComponent & { $$bindings?: Bindings } & Exports; + (internal: unknown, props: {$$events?: Events, $$slots?: Slots}): Exports; + z_$$bindings?: Bindings; +} +type $$__sveltets_2_PropsWithChildren = Props & + (Slots extends { default: any } + ? Props extends Record + ? any + : { children?: any } + : {}); + declare function $$__sveltets_2_isomorphic_component_slots< + Props extends Record, Events extends Record, Slots extends Record, Exports extends Record, Bindings extends string + >(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren, Events, Slots, Exports, Bindings>; +const Input = $$__sveltets_2_isomorphic_component_slots(__sveltets_2_partial(__sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input = InstanceType; +/*Ωignore_endΩ*/export default Input; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/export-class/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/export-class/expected-svelte5.ts new file mode 100644 index 000000000..16babe1c9 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/export-class/expected-svelte5.ts @@ -0,0 +1,10 @@ +/// +;function render() { + + class Foo {}; +; +async () => {}; +return { props: {Foo: Foo}, exports: /** @type {{Foo: typeof Foo}} */ ({}), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(['Foo'], __sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/export-const-array-destructuring/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/export-const-array-destructuring/expected-svelte5.ts new file mode 100644 index 000000000..020c3e066 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/export-const-array-destructuring/expected-svelte5.ts @@ -0,0 +1,12 @@ +/// +;function render() { + +const array = [1, 2, 3, [4]]; + + const [a, b, c, [d]] = array; +; +async () => {}; +return { props: {a: a , b: b , c: c , d: d}, exports: /** @type {{a: typeof a,b: typeof b,c: typeof c,d: typeof d}} */ ({}), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(['a','b','c','d'], __sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/export-const-object-destructuring/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/export-const-object-destructuring/expected-svelte5.ts new file mode 100644 index 000000000..6f631c790 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/export-const-object-destructuring/expected-svelte5.ts @@ -0,0 +1,21 @@ +/// +;function render() { + +const obj = { + a: 1, + b: 2, + nested: { + c: 3, + d: 4, + }, +}; + + const { + a, b, nested: { c, d: g } +} = obj; +; +async () => {}; +return { props: {a: a , b: b , c: c , g: g}, exports: /** @type {{a: typeof a,b: typeof b,c: typeof c,g: typeof g}} */ ({}), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(['a','b','c','g'], __sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/export-list/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/export-list/expected-svelte5.ts new file mode 100644 index 000000000..0a62b5780 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/export-list/expected-svelte5.ts @@ -0,0 +1,24 @@ +/// +;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 () => {}; +return { props: {name1: name1 , name2: name2 , renamed1: rename1 , renamed2: rename2 , Foo: Foo , bar: bar , baz: baz , RenamedFoo: RenameFoo , renamedbar: renamebar , renamedbaz: renamebaz}, exports: /** @type {{Foo: typeof Foo,bar: typeof bar,baz: typeof baz,RenamedFoo: typeof RenameFoo,renamedbar: typeof renamebar,renamedbaz: typeof renamebaz}} */ ({}), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(['name1','renamed1','Foo','bar','baz','RenamedFoo','renamedbar','renamedbaz'], __sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/generic-attribute-const-modifier/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/generic-attribute-const-modifier/expected-svelte5.ts new file mode 100644 index 000000000..661e2b862 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/generic-attribute-const-modifier/expected-svelte5.ts @@ -0,0 +1,29 @@ +/// +;function render() { + + let items: T/*Ωignore_startΩ*/;items = __sveltets_2_any(items);/*Ωignore_endΩ*/; +; +async () => {}; +return { props: {items: items}, slots: {}, events: {} }} +class __sveltets_Render { + props() { + return render().props; + } + events() { + return __sveltets_2_with_any_event(render()).events; + } + slots() { + return render().slots; + } + bindings() { return ""; } + exports() { return {}; } +} + +interface $$IsomorphicComponent { + new (options: import('svelte').ComponentConstructorOptions['props']>>): import('svelte').SvelteComponent['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> & { $$bindings?: ReturnType<__sveltets_Render['bindings']> } & ReturnType<__sveltets_Render['exports']>; + (internal: unknown, props: ReturnType<__sveltets_Render['props']> & {$$events?: ReturnType<__sveltets_Render['events']>}): ReturnType<__sveltets_Render['exports']>; + z_$$bindings?: ReturnType<__sveltets_Render['bindings']>; +} +const Input__SvelteComponent_: $$IsomorphicComponent = null as any; +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType>; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types.v5/expectedv2.ts new file mode 100644 index 000000000..e117495a4 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types.v5/expectedv2.ts @@ -0,0 +1,10 @@ +/// +;function render() { + + let/** @typedef {{ a: unknown, b?: boolean, c?: number, d?: string, e?: unknown, f?: unknown, g?: typeof foo }} $$ComponentProps *//** @type {$$ComponentProps} */ { a, b = true, c = 1, d = '', e = null, f = {}, g = foo } = $props(); +; +async () => {}; +return { props: /** @type {$$ComponentProps} */({}), bindings: __sveltets_$$bindings(''), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types/input.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types.v5/input.svelte similarity index 100% rename from packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types/input.svelte rename to packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types.v5/input.svelte diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types/expectedv2.ts deleted file mode 100644 index 1d4b54dcd..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types/expectedv2.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// -;function render() { - - let/** @typedef {{ a: unknown, b?: boolean, c?: number, d?: string, e?: unknown, f?: unknown, g?: typeof foo }} $$ComponentProps *//** @type {$$ComponentProps} */ { a, b = true, c = 1, d = '', e = null, f = {}, g = foo } = $props(); -; -async () => {}; -return { props: /** @type {$$ComponentProps} */({}), slots: {}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { - constructor(options = __sveltets_2_runes_constructor(__sveltets_2_partial(__sveltets_2_with_any_event(render())))) { super(options); } - $$bindings = __sveltets_$$bindings(''); -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable.v5/expectedv2.ts new file mode 100644 index 000000000..424366404 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable.v5/expectedv2.ts @@ -0,0 +1,10 @@ +/// +;function render() { + + let/** @typedef {{ a: unknown, b?: unknown }} $$ComponentProps *//** @type {$$ComponentProps} */ { a, b = $bindable() } = $props(); +; +async () => {}; +return { props: /** @type {$$ComponentProps} */({}), bindings: __sveltets_$$bindings('b'), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable/input.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable.v5/input.svelte similarity index 100% rename from packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable/input.svelte rename to packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable.v5/input.svelte diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable/expectedv2.ts deleted file mode 100644 index 9267ded4e..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable/expectedv2.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// -;function render() { - - let/** @typedef {{ a: unknown, b?: unknown }} $$ComponentProps *//** @type {$$ComponentProps} */ { a, b = $bindable() } = $props(); -; -async () => {}; -return { props: /** @type {$$ComponentProps} */({}), slots: {}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { - constructor(options = __sveltets_2_runes_constructor(__sveltets_2_partial(__sveltets_2_with_any_event(render())))) { super(options); } - $$bindings = __sveltets_$$bindings('b'); -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores.v5/expectedv2.ts new file mode 100644 index 000000000..0ef2d0f1b --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores.v5/expectedv2.ts @@ -0,0 +1,14 @@ +/// +;function render() { + + let/** @typedef {{ props: unknown }} $$ComponentProps *//** @type {$$ComponentProps} */ { props } = $props(); + let state = $state(0); + let derived = $derived(state * 2); +; +async () => { + +state; derived;}; +return { props: /** @type {$$ComponentProps} */({}), bindings: __sveltets_$$bindings(''), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores/input.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores.v5/input.svelte similarity index 100% rename from packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores/input.svelte rename to packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores.v5/input.svelte diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores/expectedv2.ts deleted file mode 100644 index 246499cf6..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores/expectedv2.ts +++ /dev/null @@ -1,16 +0,0 @@ -/// -;function render() { - - let/** @typedef {{ props: unknown }} $$ComponentProps *//** @type {$$ComponentProps} */ { props } = $props(); - let state = $state(0); - let derived = $derived(state * 2); -; -async () => { - -state; derived;}; -return { props: /** @type {$$ComponentProps} */({}), slots: {}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { - constructor(options = __sveltets_2_runes_constructor(__sveltets_2_partial(__sveltets_2_with_any_event(render())))) { super(options); } - $$bindings = __sveltets_$$bindings(''); -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-only-export.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/runes-only-export.v5/expectedv2.ts index 91d154a36..cd5d6aca0 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/runes-only-export.v5/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/runes-only-export.v5/expectedv2.ts @@ -7,8 +7,7 @@ async () => { x;}; -return { props: /** @type {Record} */ ({}), exports: /** @type {foo: typeof foo} */ ({}), slots: {}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { - get foo() { return render().exports.foo } -} \ No newline at end of file +return { props: /** @type {Record} */ ({}), exports: /** @type {{foo: typeof foo}} */ ({}), bindings: __sveltets_$$bindings(''), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-with-slots.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/runes-with-slots.v5/expectedv2.ts new file mode 100644 index 000000000..b1b7f4045 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/runes-with-slots.v5/expectedv2.ts @@ -0,0 +1,16 @@ +/// +;function render() { + + /** @type {SomeType} */ + let { a, b } = $props(); + let x = $state(0); + let y = $derived(x * 2); + +/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/; +async () => { + + { __sveltets_createSlot("default", { x,y,});}}; +return { props: /** @type {SomeType} */({}), bindings: __sveltets_$$bindings(''), slots: {'default': {x:x, y:y}}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component_slots(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-with-slots/input.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/runes-with-slots.v5/input.svelte similarity index 100% rename from packages/svelte2tsx/test/svelte2tsx/samples/runes-with-slots/input.svelte rename to packages/svelte2tsx/test/svelte2tsx/samples/runes-with-slots.v5/input.svelte diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes-with-slots/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/runes-with-slots/expectedv2.ts deleted file mode 100644 index b2f64fcb7..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/runes-with-slots/expectedv2.ts +++ /dev/null @@ -1,17 +0,0 @@ -/// -;function render() { - - /** @type {SomeType} */ - let { a, b } = $props(); - let x = $state(0); - let y = $derived(x * 2); - -/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/; -async () => { - - { __sveltets_createSlot("default", { x,y,});}}; -return { props: /** @type {SomeType} */({}), slots: {'default': {x:x, y:y}}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { - $$bindings = __sveltets_$$bindings(''); -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/runes.v5/expectedv2.ts new file mode 100644 index 000000000..756c62757 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/runes.v5/expectedv2.ts @@ -0,0 +1,13 @@ +/// +;function render() { + + /** @typedef {{a: number, b: string}} $$ComponentProps *//** @type {$$ComponentProps} */ + let { a, b } = $props(); + let x = $state(0); + let y = $derived(x * 2); +; +async () => {}; +return { props: /** @type {$$ComponentProps} */({}), bindings: __sveltets_$$bindings(''), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes/input.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/runes.v5/input.svelte similarity index 100% rename from packages/svelte2tsx/test/svelte2tsx/samples/runes/input.svelte rename to packages/svelte2tsx/test/svelte2tsx/samples/runes.v5/input.svelte diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/runes/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/runes/expectedv2.ts deleted file mode 100644 index 888397861..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/runes/expectedv2.ts +++ /dev/null @@ -1,15 +0,0 @@ -/// -;function render() { - - /** @typedef {{a: number, b: string}} $$ComponentProps *//** @type {$$ComponentProps} */ - let { a, b } = $props(); - let x = $state(0); - let y = $derived(x * 2); -; -async () => {}; -return { props: /** @type {$$ComponentProps} */({}), slots: {}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { - constructor(options = __sveltets_2_runes_constructor(__sveltets_2_partial(__sveltets_2_with_any_event(render())))) { super(options); } - $$bindings = __sveltets_$$bindings(''); -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/script-style-like-component/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/script-style-like-component/expected-svelte5.ts index 25c7a5e18..a8a97e669 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/script-style-like-component/expected-svelte5.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/script-style-like-component/expected-svelte5.ts @@ -10,6 +10,6 @@ async () => { Script} { const $$_elytS0C = __sveltets_2_ensureComponent(Style); new $$_elytS0C({ target: __sveltets_2_any(), props: {}});}}; return { props: /** @type {Record} */ ({}), slots: {}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(__sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/svelte-element/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/svelte-element/expected-svelte5.ts index 6adeb2aef..53d728686 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/svelte-element/expected-svelte5.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/svelte-element/expected-svelte5.ts @@ -12,6 +12,6 @@ async () => { { svelteHTML.createElement(tag, { "on:click":() => tag,});} { svelteHTML.createElement("a", { "data-sveltekit-preload-data":true,"href":`https://kit.svelte.dev`,});}}; return { props: /** @type {Record} */ ({}), slots: {}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(__sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune-no-changes/+page.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune-no-changes.v5/+page.svelte similarity index 100% rename from packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune-no-changes/+page.svelte rename to packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune-no-changes.v5/+page.svelte diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune-no-changes.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune-no-changes.v5/expectedv2.ts new file mode 100644 index 000000000..fe4d98e31 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune-no-changes.v5/expectedv2.ts @@ -0,0 +1,13 @@ +/// +;function render() { + + /** @typedef {{form: boolean, data: true }} $$ComponentProps *//** @type {$$ComponentProps} */ + let { form, data } = $props(); + /** @type {any} */ + const snapshot = {}; +; +async () => {}; +return { props: /** @type {$$ComponentProps} */({}), exports: /** @type {{snapshot: typeof snapshot}} */ ({}), bindings: __sveltets_$$bindings(''), slots: {}, events: {} }} +const Page__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Page__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Page__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune-no-changes/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune-no-changes/expectedv2.ts deleted file mode 100644 index c416a1d74..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune-no-changes/expectedv2.ts +++ /dev/null @@ -1,16 +0,0 @@ -/// -;function render() { - - /** @typedef {{form: boolean, data: true }} $$ComponentProps *//** @type {$$ComponentProps} */ - let { form, data } = $props(); - /** @type {any} */ - const snapshot = {}; -; -async () => {}; -return { props: /** @type {$$ComponentProps} */({}), exports: /** @type {snapshot: typeof snapshot} */ ({}), slots: {}, events: {} }} - -export default class Page__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { - constructor(options = __sveltets_2_runes_constructor(__sveltets_2_partial(__sveltets_2_with_any_event(render())))) { super(options); } - $$bindings = __sveltets_$$bindings(''); - get snapshot() { return render().exports.snapshot } -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune/+page.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune.v5/+page.svelte similarity index 100% rename from packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune/+page.svelte rename to packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune.v5/+page.svelte diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune.v5/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune.v5/expected-svelte5.ts new file mode 100644 index 000000000..b5014a5d2 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune.v5/expected-svelte5.ts @@ -0,0 +1,11 @@ +/// +;function render() { + + let/** @typedef {{ form: import('./$types.js').ActionData, data: import('./$types.js').PageData }} $$ComponentProps *//** @type {$$ComponentProps} */ { form, data } = $props(); + const snapshot/*Ωignore_startΩ*/: import('./$types.js').Snapshot/*Ωignore_endΩ*/ = {}; +; +async () => {}; +return { props: /** @type {$$ComponentProps} */({}), exports: /** @type {{snapshot: typeof snapshot}} */ ({}), bindings: __sveltets_$$bindings(''), slots: {}, events: {} }} +const Page__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Page__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Page__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune.v5/expectedv2.ts new file mode 100644 index 000000000..b5014a5d2 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune.v5/expectedv2.ts @@ -0,0 +1,11 @@ +/// +;function render() { + + let/** @typedef {{ form: import('./$types.js').ActionData, data: import('./$types.js').PageData }} $$ComponentProps *//** @type {$$ComponentProps} */ { form, data } = $props(); + const snapshot/*Ωignore_startΩ*/: import('./$types.js').Snapshot/*Ωignore_endΩ*/ = {}; +; +async () => {}; +return { props: /** @type {$$ComponentProps} */({}), exports: /** @type {{snapshot: typeof snapshot}} */ ({}), bindings: __sveltets_$$bindings(''), slots: {}, events: {} }} +const Page__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Page__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Page__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune/expectedv2.ts deleted file mode 100644 index 7195620ab..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes-$props-rune/expectedv2.ts +++ /dev/null @@ -1,14 +0,0 @@ -/// -;function render() { - - let/** @typedef {{ form: import('./$types.js').ActionData, data: import('./$types.js').PageData }} $$ComponentProps *//** @type {$$ComponentProps} */ { form, data } = $props(); - const snapshot/*Ωignore_startΩ*/: import('./$types.js').Snapshot/*Ωignore_endΩ*/ = {}; -; -async () => {}; -return { props: /** @type {$$ComponentProps} */({}), exports: /** @type {snapshot: typeof snapshot} */ ({}), slots: {}, events: {} }} - -export default class Page__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { - constructor(options = __sveltets_2_runes_constructor(__sveltets_2_partial(__sveltets_2_with_any_event(render())))) { super(options); } - $$bindings = __sveltets_$$bindings(''); - get snapshot() { return render().exports.snapshot } -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes/expected-svelte5.ts new file mode 100644 index 000000000..f025668b0 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/sveltekit-autotypes/expected-svelte5.ts @@ -0,0 +1,16 @@ +/// +;function render() { + + let data/*Ωignore_startΩ*/: import('./$types.js').PageData;data = __sveltets_2_any(data);/*Ωignore_endΩ*/; + let form/*Ωignore_startΩ*/: import('./$types.js').ActionData;form = __sveltets_2_any(form);/*Ωignore_endΩ*/; + const snapshot/*Ωignore_startΩ*/: import('./$types.js').Snapshot/*Ωignore_endΩ*/ = {}; + + let nope/*Ωignore_startΩ*/;nope = __sveltets_2_any(nope);/*Ωignore_endΩ*/; + let form/*Ωignore_startΩ*/: import('./$types.js').ActionData/*Ωignore_endΩ*/ = {} + let data: number/*Ωignore_startΩ*/;data = __sveltets_2_any(data);/*Ωignore_endΩ*/; +; +async () => {}; +return { props: {data: data , form: form , snapshot: snapshot , nope: nope}, exports: /** @type {{snapshot: typeof snapshot}} */ ({}), slots: {}, events: {} }} +const Page__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(['form','snapshot'], __sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Page__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Page__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/transforms-interfaces-dts/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/transforms-interfaces-dts/expected-svelte5.ts new file mode 100644 index 000000000..a1b8217a1 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/transforms-interfaces-dts/expected-svelte5.ts @@ -0,0 +1,36 @@ +import { SvelteComponentTyped } from "svelte" + +; +import type { Foo } from './foo'; +function render() { + + + let foo: Foo/*Ωignore_startΩ*/;foo = __sveltets_2_any(foo);/*Ωignore_endΩ*/; + type Bar1 ={ + a: true; + } + type Bar2 = Bar1 & { + b: false; + } + type Bar3 = Bar1 & Bar2 & { + c: false; + } + type Bar4 = Bar1 & Bar2 & { + c: false; + } + let bar: Bar3/*Ωignore_startΩ*/;bar = __sveltets_2_any(bar);/*Ωignore_endΩ*/; +; +async () => {}; +return { props: {foo: foo , bar: bar}, slots: {}, events: {} }} +interface $$__sveltets_2_IsomorphicComponent = any, Events extends Record = any, Slots extends Record = any, Exports = {}, Bindings = string> { + new (options: import('svelte').ComponentConstructorOptions): import('svelte').SvelteComponent & { $$bindings?: Bindings } & Exports; + (internal: unknown, props: Props & {$$events?: Events, $$slots?: Slots}): Exports; + z_$$bindings?: Bindings; +} + +declare function $$__sveltets_2_isomorphic_component< + Props extends Record, Events extends Record, Slots extends Record, Exports extends Record, Bindings extends string +>(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): $$__sveltets_2_IsomorphicComponent; +const Input = $$__sveltets_2_isomorphic_component(__sveltets_2_partial(__sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input = InstanceType; +/*Ωignore_endΩ*/export default Input; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-interface/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-interface/expected-svelte5.ts new file mode 100644 index 000000000..043d48da5 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-interface/expected-svelte5.ts @@ -0,0 +1,37 @@ +/// +;function render() { + + + type $$Props = { + exported1: string; + exported2?: string; + name1?: string; + name2: string; + renamed1?: string; + renamed2: string; + } + + let exported1: string/*Ωignore_startΩ*/;exported1 = __sveltets_2_any(exported1);/*Ωignore_endΩ*/; + let exported2: string = ''/*Ωignore_startΩ*/;exported2 = __sveltets_2_any(exported2);/*Ωignore_endΩ*/; + + 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 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 () => {}; +return { props: { ...__sveltets_2_ensureRightProps<{exported1: string,exported2?: string,name1?: string,name2: string,renamed1?: string,renamed2: string}>(__sveltets_2_any("") as $$Props)} as {Foo?: typeof Foo,bar?: typeof bar,baz?: string,RenamedFoo?: typeof RenameFoo,renamedbar?: typeof renamebar,renamedbaz?: string} & $$Props, exports: {} as any as { Foo: typeof Foo,bar: typeof bar,baz: string,RenamedFoo: typeof RenameFoo,renamedbar: typeof renamebar,renamedbaz: string }, slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-type/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-type/expected-svelte5.ts new file mode 100644 index 000000000..1999cb767 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-type/expected-svelte5.ts @@ -0,0 +1,37 @@ +/// +;function render() { + + + interface $$Props { + exported1: string; + exported2?: string; + name1?: string; + name2: string; + renamed1?: string; + renamed2: string; + } + + let exported1: string/*Ωignore_startΩ*/;exported1 = __sveltets_2_any(exported1);/*Ωignore_endΩ*/; + let exported2: string = ''/*Ωignore_startΩ*/;exported2 = __sveltets_2_any(exported2);/*Ωignore_endΩ*/; + + 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 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 () => {}; +return { props: { ...__sveltets_2_ensureRightProps<{exported1: string,exported2?: string,name1?: string,name2: string,renamed1?: string,renamed2: string}>(__sveltets_2_any("") as $$Props)} as {Foo?: typeof Foo,bar?: typeof bar,baz?: string,RenamedFoo?: typeof RenameFoo,renamedbar?: typeof renamebar,renamedbaz?: string} & $$Props, exports: {} as any as { Foo: typeof Foo,bar: typeof bar,baz: string,RenamedFoo: typeof RenameFoo,renamedbar: typeof renamebar,renamedbaz: string }, slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-with-$$props/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-with-$$props/expected-svelte5.ts new file mode 100644 index 000000000..61aa4ab63 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$Props-with-$$props/expected-svelte5.ts @@ -0,0 +1,19 @@ +/// +;function render() { let $$props = __sveltets_2_allPropsType(); + + interface $$Props { + /** + * comment + */ + a: boolean; + b?: string; + } + function c() {} +; +async () => { + +$$props;}; +return { props: { ...__sveltets_2_ensureRightProps<{}>(__sveltets_2_any("") as $$Props)} as {c?: typeof c} & $$Props, exports: {} as any as { c: typeof c }, slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics-accessor-dts/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics-accessor-dts/expected-svelte5.ts new file mode 100644 index 000000000..5e64771fe --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics-accessor-dts/expected-svelte5.ts @@ -0,0 +1,34 @@ +import { SvelteComponentTyped } from "svelte" + +;function render/*Ωignore_startΩ*//*Ωignore_endΩ*/() { + + + + let a: A/*Ωignore_startΩ*/;a = __sveltets_2_any(a);/*Ωignore_endΩ*/; +; +async () => { + + { svelteHTML.createElement("svelte:options", {"accessors":true,});}}; +return { props: {a: a} as {a: A}, exports: {} as any as { a: A }, slots: {}, events: {} }} +class __sveltets_Render { + props() { + return render().props; + } + events() { + return __sveltets_2_with_any_event(render()).events; + } + slots() { + return render().slots; + } + bindings() { return ""; } + exports() { return render().exports; } +} + +interface $$IsomorphicComponent { + new (options: import('svelte').ComponentConstructorOptions['props']>>): import('svelte').SvelteComponent['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> & { $$bindings?: ReturnType<__sveltets_Render['bindings']> } & ReturnType<__sveltets_Render['exports']>; + (internal: unknown, props: ReturnType<__sveltets_Render['props']> & {$$events?: ReturnType<__sveltets_Render['events']>}): ReturnType<__sveltets_Render['exports']>; + z_$$bindings?: ReturnType<__sveltets_Render['bindings']>; +} +const Input: $$IsomorphicComponent = null as any; +/*Ωignore_startΩ*/type Input = InstanceType>; +/*Ωignore_endΩ*/export default Input; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics-accessor/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics-accessor/expected-svelte5.ts new file mode 100644 index 000000000..d7797e65c --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics-accessor/expected-svelte5.ts @@ -0,0 +1,33 @@ +/// +;function render/*Ωignore_startΩ*//*Ωignore_endΩ*/() { + + + + let a: A/*Ωignore_startΩ*/;a = __sveltets_2_any(a);/*Ωignore_endΩ*/; +; +async () => { + + { svelteHTML.createElement("svelte:options", {"accessors":true,});}}; +return { props: {a: a} as {a: A}, exports: {} as any as { a: A }, slots: {}, events: {} }} +class __sveltets_Render { + props() { + return render().props; + } + events() { + return __sveltets_2_with_any_event(render()).events; + } + slots() { + return render().slots; + } + bindings() { return ""; } + exports() { return render().exports; } +} + +interface $$IsomorphicComponent { + new (options: import('svelte').ComponentConstructorOptions['props']>>): import('svelte').SvelteComponent['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> & { $$bindings?: ReturnType<__sveltets_Render['bindings']> } & ReturnType<__sveltets_Render['exports']>; + (internal: unknown, props: ReturnType<__sveltets_Render['props']> & {$$events?: ReturnType<__sveltets_Render['events']>}): ReturnType<__sveltets_Render['exports']>; + z_$$bindings?: ReturnType<__sveltets_Render['bindings']>; +} +const Input__SvelteComponent_: $$IsomorphicComponent = null as any; +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType>; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics-dts/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics-dts/expected-svelte5.ts index 221fa6a8d..fa827e2c1 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics-dts/expected-svelte5.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics-dts/expected-svelte5.ts @@ -23,7 +23,7 @@ function render/*Ωignore_startΩ*//*Ωig async () => { { __sveltets_createSlot("default", { c,});}}; -return { props: {a: a , b: b , c: c , getA: getA} as {a: A, b: B, c: C, getA?: typeof getA}, slots: {'default': {c:c}}, events: {...__sveltets_2_toEventTypings<{a: A}>()} }} +return { props: {a: a , b: b , c: c , getA: getA} as {a: A, b: B, c: C, getA?: typeof getA}, exports: {} as any as { getA: typeof getA }, slots: {'default': {c:c}}, events: {...__sveltets_2_toEventTypings<{a: A}>()} }} class __sveltets_Render { props() { return render().props; @@ -34,11 +34,15 @@ class __sveltets_Render { slots() { return render().slots; } + bindings() { return ""; } + exports() { return render().exports; } } -export type InputProps = ReturnType<__sveltets_Render['props']>; -export type InputEvents = ReturnType<__sveltets_Render['events']>; -export type InputSlots = ReturnType<__sveltets_Render['slots']>; -export default class Input extends SvelteComponentTyped, InputEvents, InputSlots> { - get getA() { return __sveltets_2_nonNullable(this.$$prop_def.getA) } -} \ No newline at end of file +interface $$IsomorphicComponent { + new (options: import('svelte').ComponentConstructorOptions['props']>& {children?: any}>): import('svelte').SvelteComponent['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> & { $$bindings?: ReturnType<__sveltets_Render['bindings']> } & ReturnType<__sveltets_Render['exports']>; + (internal: unknown, props: ReturnType<__sveltets_Render['props']> & {$$events?: ReturnType<__sveltets_Render['events']>, $$slots?: ReturnType<__sveltets_Render['slots']>, children?: any}): ReturnType<__sveltets_Render['exports']>; + z_$$bindings?: ReturnType<__sveltets_Render['bindings']>; +} +const Input: $$IsomorphicComponent = null as any; +/*Ωignore_startΩ*/type Input = InstanceType>; +/*Ωignore_endΩ*/export default Input; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics-interface-references/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics-interface-references/expected-svelte5.ts new file mode 100644 index 000000000..c926b0db5 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics-interface-references/expected-svelte5.ts @@ -0,0 +1,45 @@ +/// +; +import type Foo from 'somewhere'; +interface ReferencedByGeneric { + b: true; + f: Foo; + } +function render/*Ωignore_startΩ*//*Ωignore_endΩ*/() { + + + interface ReferencesGeneric { + a: A; + } + + + + + + let a: ReferencesGeneric/*Ωignore_startΩ*/;a = __sveltets_2_any(a);/*Ωignore_endΩ*/; + let b: B/*Ωignore_startΩ*/;b = __sveltets_2_any(b);/*Ωignore_endΩ*/; +; +async () => {}; +return { props: {a: a , b: b} as {a: ReferencesGeneric, b: B}, slots: {}, events: {} }} +class __sveltets_Render { + props() { + return render().props; + } + events() { + return __sveltets_2_with_any_event(render()).events; + } + slots() { + return render().slots; + } + bindings() { return ""; } + exports() { return {}; } +} + +interface $$IsomorphicComponent { + new (options: import('svelte').ComponentConstructorOptions['props']>>): import('svelte').SvelteComponent['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> & { $$bindings?: ReturnType<__sveltets_Render['bindings']> } & ReturnType<__sveltets_Render['exports']>; + (internal: unknown, props: ReturnType<__sveltets_Render['props']> & {$$events?: ReturnType<__sveltets_Render['events']>}): ReturnType<__sveltets_Render['exports']>; + z_$$bindings?: ReturnType<__sveltets_Render['bindings']>; +} +const Input__SvelteComponent_: $$IsomorphicComponent = null as any; +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType>; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics/expected-svelte5.ts index e08603058..fc7f08c75 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics/expected-svelte5.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-$$generics/expected-svelte5.ts @@ -23,7 +23,7 @@ function render/*Ωignore_startΩ*//*Ωig async () => { { __sveltets_createSlot("default", { c,});}}; -return { props: {a: a , b: b , c: c , getA: getA} as {a: A, b: B, c: C, getA?: typeof getA}, slots: {'default': {c:c}}, events: {...__sveltets_2_toEventTypings<{a: A}>()} }} +return { props: {a: a , b: b , c: c , getA: getA} as {a: A, b: B, c: C, getA?: typeof getA}, exports: {} as any as { getA: typeof getA }, slots: {'default': {c:c}}, events: {...__sveltets_2_toEventTypings<{a: A}>()} }} class __sveltets_Render { props() { return render().props; @@ -34,10 +34,15 @@ class __sveltets_Render { slots() { return render().slots; } + bindings() { return ""; } + exports() { return render().exports; } } - -import { SvelteComponentTyped as __SvelteComponentTyped__ } from "svelte" -export default class Input__SvelteComponent_ extends __SvelteComponentTyped__['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> { - get getA() { return __sveltets_2_nonNullable(this.$$prop_def.getA) } -} \ No newline at end of file +interface $$IsomorphicComponent { + new (options: import('svelte').ComponentConstructorOptions['props']>& {children?: any}>): import('svelte').SvelteComponent['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> & { $$bindings?: ReturnType<__sveltets_Render['bindings']> } & ReturnType<__sveltets_Render['exports']>; + (internal: unknown, props: ReturnType<__sveltets_Render['props']> & {$$events?: ReturnType<__sveltets_Render['events']>, $$slots?: ReturnType<__sveltets_Render['slots']>, children?: any}): ReturnType<__sveltets_Render['exports']>; + z_$$bindings?: ReturnType<__sveltets_Render['bindings']>; +} +const Input__SvelteComponent_: $$IsomorphicComponent = null as any; +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType>; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-creates-dts/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-creates-dts/expected-svelte5.ts index 075731345..96ce0ca3e 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-creates-dts/expected-svelte5.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-creates-dts/expected-svelte5.ts @@ -23,10 +23,20 @@ async () => { { svelteHTML.createElement("button", { "on:click":undefined,}); } { __sveltets_createSlot("default", {bar,}); }}; return { props: {bar: bar , foobar: foobar} as {bar: Bar, foobar?: typeof foobar}, slots: {'default': {bar:bar}}, events: {...__sveltets_2_toEventTypings<{swipe: string}>(), 'click':__sveltets_2_mapElementEvent('click')} }} -const __propDef = __sveltets_2_with_any_event(render()); -export type InputProps = typeof __propDef.props; -export type InputEvents = typeof __propDef.events; -export type InputSlots = typeof __propDef.slots; - -export default class Input extends SvelteComponentTyped { -} \ No newline at end of file +interface $$__sveltets_2_IsomorphicComponent = any, Events extends Record = any, Slots extends Record = any, Exports = {}, Bindings = string> { + new (options: import('svelte').ComponentConstructorOptions): import('svelte').SvelteComponent & { $$bindings?: Bindings } & Exports; + (internal: unknown, props: Props & {$$events?: Events, $$slots?: Slots}): Exports; + z_$$bindings?: Bindings; +} +type $$__sveltets_2_PropsWithChildren = Props & + (Slots extends { default: any } + ? Props extends Record + ? any + : { children?: any } + : {}); + declare function $$__sveltets_2_isomorphic_component_slots< + Props extends Record, Events extends Record, Slots extends Record, Exports extends Record, Bindings extends string + >(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren, Events, Slots, Exports, Bindings>; +const Input = $$__sveltets_2_isomorphic_component_slots(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Input = InstanceType; +/*Ωignore_endΩ*/export default Input; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-export-const/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-export-const/expected-svelte5.ts new file mode 100644 index 000000000..12d0eb57b --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-export-const/expected-svelte5.ts @@ -0,0 +1,11 @@ +/// +;function render() { + + const name: string = "world"; + const SOME = 1, CONSTANT = 2; +; +async () => {}; +return { props: {name: name , SOME: SOME , CONSTANT: CONSTANT} as {name?: string, SOME?: typeof SOME, CONSTANT?: typeof CONSTANT}, exports: {} as any as { name: string,SOME: typeof SOME,CONSTANT: typeof CONSTANT }, slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-export-list/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-export-list/expected-svelte5.ts new file mode 100644 index 000000000..8e012d74c --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-export-list/expected-svelte5.ts @@ -0,0 +1,25 @@ +/// +;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 () => {}; +return { props: {name1: name1 , name2: name2 , name3: name3 , name4: name4 , renamed1: rename1 , renamed2: rename2 , Foo: Foo , bar: bar , baz: baz , RenamedFoo: RenameFoo , renamedbar: renamebar , renamedbaz: renamebaz} 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}, exports: {} as any as { Foo: typeof Foo,bar: typeof bar,baz: string,RenamedFoo: typeof RenameFoo,renamedbar: typeof renamebar,renamedbaz: string }, slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-generics-attribute1/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-generics-attribute1/expected-svelte5.ts index bf76800a4..46cbe23a1 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-generics-attribute1/expected-svelte5.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-generics-attribute1/expected-svelte5.ts @@ -19,7 +19,7 @@ function render() { async () => { { __sveltets_createSlot("default", { c,});}}; -return { props: {a: a , b: b , c: c , getA: getA} as {a: A, b: B, c: C, getA?: typeof getA}, slots: {'default': {c:c}}, events: {...__sveltets_2_toEventTypings<{a: A}>()} }} +return { props: {a: a , b: b , c: c , getA: getA} as {a: A, b: B, c: C, getA?: typeof getA}, exports: {} as any as { getA: typeof getA }, slots: {'default': {c:c}}, events: {...__sveltets_2_toEventTypings<{a: A}>()} }} class __sveltets_Render { props() { return render().props; @@ -30,10 +30,15 @@ class __sveltets_Render { slots() { return render().slots; } + bindings() { return ""; } + exports() { return render().exports; } } - -import { SvelteComponentTyped as __SvelteComponentTyped__ } from "svelte" -export default class Input__SvelteComponent_ extends __SvelteComponentTyped__['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> { - get getA() { return __sveltets_2_nonNullable(this.$$prop_def.getA) } -} \ No newline at end of file +interface $$IsomorphicComponent { + new (options: import('svelte').ComponentConstructorOptions['props']>& {children?: any}>): import('svelte').SvelteComponent['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> & { $$bindings?: ReturnType<__sveltets_Render['bindings']> } & ReturnType<__sveltets_Render['exports']>; + (internal: unknown, props: ReturnType<__sveltets_Render['props']> & {$$events?: ReturnType<__sveltets_Render['events']>, $$slots?: ReturnType<__sveltets_Render['slots']>, children?: any}): ReturnType<__sveltets_Render['exports']>; + z_$$bindings?: ReturnType<__sveltets_Render['bindings']>; +} +const Input__SvelteComponent_: $$IsomorphicComponent = null as any; +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType>; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-generics-attribute2/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-generics-attribute2/expected-svelte5.ts new file mode 100644 index 000000000..3a65508e1 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-generics-attribute2/expected-svelte5.ts @@ -0,0 +1,29 @@ +/// +;function render() { + + let a: T/*Ωignore_startΩ*/;a = __sveltets_2_any(a);/*Ωignore_endΩ*/; +; +async () => {}; +return { props: {a: a} as {a: T}, slots: {}, events: {} }} +class __sveltets_Render { + props() { + return render().props; + } + events() { + return __sveltets_2_with_any_event(render()).events; + } + slots() { + return render().slots; + } + bindings() { return ""; } + exports() { return {}; } +} + +interface $$IsomorphicComponent { + new (options: import('svelte').ComponentConstructorOptions['props']>>): import('svelte').SvelteComponent['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> & { $$bindings?: ReturnType<__sveltets_Render['bindings']> } & ReturnType<__sveltets_Render['exports']>; + (internal: unknown, props: ReturnType<__sveltets_Render['props']> & {$$events?: ReturnType<__sveltets_Render['events']>}): ReturnType<__sveltets_Render['exports']>; + z_$$bindings?: ReturnType<__sveltets_Render['bindings']>; +} +const Input__SvelteComponent_: $$IsomorphicComponent = null as any; +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType>; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-best-effort-types/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-best-effort-types.v5/expectedv2.ts similarity index 51% rename from packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-best-effort-types/expectedv2.ts rename to packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-best-effort-types.v5/expectedv2.ts index 530b51e2e..c44a04d24 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-best-effort-types/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-best-effort-types.v5/expectedv2.ts @@ -4,9 +4,7 @@ let { a, b = true, c = 1, d = '', e = null, f = {}, g = foo, h = null as Bar, i = null as any as Baz }: $$ComponentProps = $props(); ; async () => {}; -return { props: {} as any as $$ComponentProps, slots: {}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_with_any_event(render())) { - constructor(options = __sveltets_2_runes_constructor(__sveltets_2_with_any_event(render()))) { super(options); } - $$bindings = __sveltets_$$bindings(''); -} \ No newline at end of file +return { props: {} as any as $$ComponentProps, bindings: __sveltets_$$bindings(''), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-best-effort-types/input.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-best-effort-types.v5/input.svelte similarity index 100% rename from packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-best-effort-types/input.svelte rename to packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-best-effort-types.v5/input.svelte diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-bindable.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-bindable.v5/expectedv2.ts new file mode 100644 index 000000000..9f45193a5 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-bindable.v5/expectedv2.ts @@ -0,0 +1,10 @@ +/// +;function render() { +/*Ωignore_startΩ*/;type $$ComponentProps = { a: unknown, b?: unknown, c?: number };/*Ωignore_endΩ*/ + let { a, b = $bindable(), c = $bindable(0) as number }: $$ComponentProps = $props(); +; +async () => {}; +return { props: {} as any as $$ComponentProps, bindings: __sveltets_$$bindings('b', 'c'), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-bindable/input.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-bindable.v5/input.svelte similarity index 100% rename from packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-bindable/input.svelte rename to packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-bindable.v5/input.svelte diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-bindable/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-bindable/expectedv2.ts deleted file mode 100644 index 0f7c3f59b..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-bindable/expectedv2.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// -;function render() { -/*Ωignore_startΩ*/;type $$ComponentProps = { a: unknown, b?: unknown, c?: number };/*Ωignore_endΩ*/ - let { a, b = $bindable(), c = $bindable(0) as number }: $$ComponentProps = $props(); -; -async () => {}; -return { props: {} as any as $$ComponentProps, slots: {}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_with_any_event(render())) { - constructor(options = __sveltets_2_runes_constructor(__sveltets_2_with_any_event(render()))) { super(options); } - $$bindings = __sveltets_$$bindings('b', 'c'); -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-generics.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-generics.v5/expectedv2.ts new file mode 100644 index 000000000..31d30275a --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-generics.v5/expectedv2.ts @@ -0,0 +1,31 @@ +/// +;function render() { +;type $$ComponentProps = { a: T, b: string }; + let { a, b }:/*Ωignore_startΩ*/$$ComponentProps/*Ωignore_endΩ*/ = $props(); + let x = $state(0); + let y = $derived(x * 2); +; +async () => {}; +return { props: {} as any as $$ComponentProps, bindings: __sveltets_$$bindings(''), slots: {}, events: {} }} +class __sveltets_Render { + props() { + return render().props; + } + events() { + return __sveltets_2_with_any_event(render()).events; + } + slots() { + return render().slots; + } + bindings() { return __sveltets_$$bindings(''); } + exports() { return {}; } +} + +interface $$IsomorphicComponent { + new (options: import('svelte').ComponentConstructorOptions['props']>>): import('svelte').SvelteComponent['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> & { $$bindings?: ReturnType<__sveltets_Render['bindings']> } & ReturnType<__sveltets_Render['exports']>; + (internal: unknown, props: ReturnType<__sveltets_Render['props']> & {$$events?: ReturnType<__sveltets_Render['events']>}): ReturnType<__sveltets_Render['exports']>; + z_$$bindings?: ReturnType<__sveltets_Render['bindings']>; +} +const Input__SvelteComponent_: $$IsomorphicComponent = null as any; +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType>; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-generics/input.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-generics.v5/input.svelte similarity index 100% rename from packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-generics/input.svelte rename to packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-generics.v5/input.svelte diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-generics/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-generics/expectedv2.ts deleted file mode 100644 index e2a415314..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-generics/expectedv2.ts +++ /dev/null @@ -1,27 +0,0 @@ -/// -;function render() { -;type $$ComponentProps = { a: T, b: string }; - let { a, b }:/*Ωignore_startΩ*/$$ComponentProps/*Ωignore_endΩ*/ = $props(); - let x = $state(0); - let y = $derived(x * 2); -; -async () => {}; -return { props: {} as any as $$ComponentProps, slots: {}, events: {} }} -class __sveltets_Render { - props() { - return render().props; - } - events() { - return __sveltets_2_with_any_event(render()).events; - } - slots() { - return render().slots; - } -} - - -import { SvelteComponentTyped as __SvelteComponentTyped__ } from "svelte" -export default class Input__SvelteComponent_ extends __SvelteComponentTyped__['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> { - constructor(options: import('svelte').ComponentConstructorOptions['props']>>) { super(options); } - $$bindings = __sveltets_$$bindings(''); -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-with-slot.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-with-slot.v5/expectedv2.ts new file mode 100644 index 000000000..824c94b1f --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-with-slot.v5/expectedv2.ts @@ -0,0 +1,35 @@ +/// +;function render() { + + type Props = { a: T, b: string }; + let { a, b }: Props = $props(); + let x = $state(0); + let y = $derived(x * 2); + +/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/; +async () => { + + { __sveltets_createSlot("default", { x,y,});}}; +return { props: {} as any as Props, bindings: __sveltets_$$bindings(''), slots: {'default': {x:x, y:y}}, events: {} }} +class __sveltets_Render { + props() { + return render().props; + } + events() { + return __sveltets_2_with_any_event(render()).events; + } + slots() { + return render().slots; + } + bindings() { return __sveltets_$$bindings(''); } + exports() { return {}; } +} + +interface $$IsomorphicComponent { + new (options: import('svelte').ComponentConstructorOptions['props']>& {children?: any}>): import('svelte').SvelteComponent['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> & { $$bindings?: ReturnType<__sveltets_Render['bindings']> } & ReturnType<__sveltets_Render['exports']>; + (internal: unknown, props: ReturnType<__sveltets_Render['props']> & {$$events?: ReturnType<__sveltets_Render['events']>, $$slots?: ReturnType<__sveltets_Render['slots']>, children?: any}): ReturnType<__sveltets_Render['exports']>; + z_$$bindings?: ReturnType<__sveltets_Render['bindings']>; +} +const Input__SvelteComponent_: $$IsomorphicComponent = null as any; +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType>; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-with-slot/input.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-with-slot.v5/input.svelte similarity index 100% rename from packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-with-slot/input.svelte rename to packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-with-slot.v5/input.svelte diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-with-slot/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-with-slot/expectedv2.ts deleted file mode 100644 index ab9ba5dc8..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes-with-slot/expectedv2.ts +++ /dev/null @@ -1,30 +0,0 @@ -/// -;function render() { - - type Props = { a: T, b: string }; - let { a, b }: Props = $props(); - let x = $state(0); - let y = $derived(x * 2); - -/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/; -async () => { - - { __sveltets_createSlot("default", { x,y,});}}; -return { props: {} as any as Props, slots: {'default': {x:x, y:y}}, events: {} }} -class __sveltets_Render { - props() { - return render().props; - } - events() { - return __sveltets_2_with_any_event(render()).events; - } - slots() { - return render().slots; - } -} - - -import { SvelteComponentTyped as __SvelteComponentTyped__ } from "svelte" -export default class Input__SvelteComponent_ extends __SvelteComponentTyped__['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> { - $$bindings = __sveltets_$$bindings(''); -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes.v5/expectedv2.ts new file mode 100644 index 000000000..ab3ec7fdb --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes.v5/expectedv2.ts @@ -0,0 +1,12 @@ +/// +;function render() { +;type $$ComponentProps = { a: number, b: string }; + let { a, b }:/*Ωignore_startΩ*/$$ComponentProps/*Ωignore_endΩ*/ = $props(); + let x = $state(0); + let y = $derived(x * 2); +; +async () => {}; +return { props: {} as any as $$ComponentProps, bindings: __sveltets_$$bindings(''), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes/input.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes.v5/input.svelte similarity index 100% rename from packages/svelte2tsx/test/svelte2tsx/samples/ts-runes/input.svelte rename to packages/svelte2tsx/test/svelte2tsx/samples/ts-runes.v5/input.svelte diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes/expectedv2.ts deleted file mode 100644 index a4b6020df..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-runes/expectedv2.ts +++ /dev/null @@ -1,14 +0,0 @@ -/// -;function render() { -;type $$ComponentProps = { a: number, b: string }; - let { a, b }:/*Ωignore_startΩ*/$$ComponentProps/*Ωignore_endΩ*/ = $props(); - let x = $state(0); - let y = $derived(x * 2); -; -async () => {}; -return { props: {} as any as $$ComponentProps, slots: {}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_with_any_event(render())) { - constructor(options = __sveltets_2_runes_constructor(__sveltets_2_with_any_event(render()))) { super(options); } - $$bindings = __sveltets_$$bindings(''); -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-script-tag-generics/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-script-tag-generics/expected-svelte5.ts new file mode 100644 index 000000000..6fddc7449 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-script-tag-generics/expected-svelte5.ts @@ -0,0 +1,29 @@ +/// +;function render>() { + + let init: T/*Ωignore_startΩ*/;init = __sveltets_2_any(init);/*Ωignore_endΩ*/; +; +async () => {}; +return { props: {init: init} as {init: T}, slots: {}, events: {} }} +class __sveltets_Render> { + props() { + return render().props; + } + events() { + return __sveltets_2_with_any_event(render()).events; + } + slots() { + return render().slots; + } + bindings() { return ""; } + exports() { return {}; } +} + +interface $$IsomorphicComponent { + new >(options: import('svelte').ComponentConstructorOptions['props']>>): import('svelte').SvelteComponent['props']>, ReturnType<__sveltets_Render['events']>, ReturnType<__sveltets_Render['slots']>> & { $$bindings?: ReturnType<__sveltets_Render['bindings']> } & ReturnType<__sveltets_Render['exports']>; + >(internal: unknown, props: ReturnType<__sveltets_Render['props']> & {$$events?: ReturnType<__sveltets_Render['events']>}): ReturnType<__sveltets_Render['exports']>; + z_$$bindings?: ReturnType<__sveltets_Render['bindings']>; +} +const Input__SvelteComponent_: $$IsomorphicComponent = null as any; +/*Ωignore_startΩ*/type Input__SvelteComponent_> = InstanceType>; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune-unchanged/+page.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune-unchanged.v5/+page.svelte similarity index 100% rename from packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune-unchanged/+page.svelte rename to packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune-unchanged.v5/+page.svelte diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune-unchanged.v5/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune-unchanged.v5/expectedv2.ts new file mode 100644 index 000000000..522d58fd2 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune-unchanged.v5/expectedv2.ts @@ -0,0 +1,11 @@ +/// +;function render() { + + const snapshot: any = {};;type $$ComponentProps = {form: boolean, data: true }; + let { form, data }:/*Ωignore_startΩ*/$$ComponentProps/*Ωignore_endΩ*/ = $props(); +; +async () => {}; +return { props: {} as any as $$ComponentProps, exports: {} as any as { snapshot: any }, bindings: __sveltets_$$bindings(''), slots: {}, events: {} }} +const Page__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Page__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Page__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune-unchanged/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune-unchanged/expectedv2.ts deleted file mode 100644 index d9d8a85dc..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune-unchanged/expectedv2.ts +++ /dev/null @@ -1,14 +0,0 @@ -/// -;function render() { - - const snapshot: any = {};;type $$ComponentProps = {form: boolean, data: true }; - let { form, data }:/*Ωignore_startΩ*/$$ComponentProps/*Ωignore_endΩ*/ = $props(); -; -async () => {}; -return { props: {} as any as $$ComponentProps, exports: {} as any as { snapshot: any }, slots: {}, events: {} }} - -export default class Page__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_with_any_event(render())) { - constructor(options = __sveltets_2_runes_constructor(__sveltets_2_with_any_event(render()))) { super(options); } - $$bindings = __sveltets_$$bindings(''); - get snapshot() { return render().exports.snapshot } -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune/+page.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune.v5/+page.svelte similarity index 100% rename from packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune/+page.svelte rename to packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune.v5/+page.svelte diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune.v5/expectedv2.ts similarity index 51% rename from packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune/expectedv2.ts rename to packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune.v5/expectedv2.ts index b3afa9ba5..04db7b55e 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune/expectedv2.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-sveltekit-autotypes-$props-rune.v5/expectedv2.ts @@ -5,10 +5,7 @@ let { form, data }: $$ComponentProps = $props(); ; async () => {}; -return { props: {} as any as $$ComponentProps, exports: {} as any as { snapshot: typeof snapshot }, slots: {}, events: {} }} - -export default class Page__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_with_any_event(render())) { - constructor(options = __sveltets_2_runes_constructor(__sveltets_2_with_any_event(render()))) { super(options); } - $$bindings = __sveltets_$$bindings(''); - get snapshot() { return render().exports.snapshot } -} \ No newline at end of file +return { props: {} as any as $$ComponentProps, exports: {} as any as { snapshot: typeof snapshot }, bindings: __sveltets_$$bindings(''), slots: {}, events: {} }} +const Page__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_with_any_event(render())); +/*Ωignore_startΩ*/type Page__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Page__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/uses-$$slots-script/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/uses-$$slots-script/expected-svelte5.ts deleted file mode 100644 index 1ac74f8c9..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/uses-$$slots-script/expected-svelte5.ts +++ /dev/null @@ -1,17 +0,0 @@ -/// -;function render() { let $$slots = __sveltets_2_slotsType({'foo': '', 'dashed-name': '', 'default': ''}); - - let name = $$slots.foo; - let dashedName = $$slots['dashed-name']; - -/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/; -async () => { - - { svelteHTML.createElement("h1", {});name; } - { __sveltets_createSlot("foo", { });} - { __sveltets_createSlot("dashed-name", { });} - { __sveltets_createSlot("default", {});}}; -return { props: /** @type {Record} */ ({}), slots: {'foo': {}, 'dashed-name': {}, 'default': {}}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/uses-$$slots/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/uses-$$slots/expected-svelte5.ts deleted file mode 100644 index 1fa7400a5..000000000 --- a/packages/svelte2tsx/test/svelte2tsx/samples/uses-$$slots/expected-svelte5.ts +++ /dev/null @@ -1,13 +0,0 @@ -/// -;function render() { let $$slots = __sveltets_2_slotsType({'foo': '', 'dashed-name': '', 'default': ''}); -/*Ωignore_startΩ*/;const __sveltets_createSlot = __sveltets_2_createCreateSlot();/*Ωignore_endΩ*/ -async () => { { svelteHTML.createElement("h1", {});$$slots.foo; } - { svelteHTML.createElement("h1", {});$$slots['dashed-name']; } - - { __sveltets_createSlot("foo", { });} - { __sveltets_createSlot("dashed-name", { });} - { __sveltets_createSlot("default", {});}}; -return { props: /** @type {Record} */ ({}), slots: {'foo': {}, 'dashed-name': {}, 'default': {}}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-attr-not-present/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-attr-not-present/expected-svelte5.ts new file mode 100644 index 000000000..007bc4ec6 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-attr-not-present/expected-svelte5.ts @@ -0,0 +1,12 @@ +/// +;function render() { + + let foo: number = undefined/*Ωignore_startΩ*/;foo = __sveltets_2_any(foo);/*Ωignore_endΩ*/ + const bar: string = '' +; +async () => { { svelteHTML.createElement("svelte:options", {});} +}; +return { props: {foo: foo , bar: bar}, exports: /** @type {{bar: string}} */ ({}), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(['foo','bar'], __sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-attr-present/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-attr-present/expected-svelte5.ts new file mode 100644 index 000000000..3d246c4a6 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-attr-present/expected-svelte5.ts @@ -0,0 +1,15 @@ +/// +;function render() { + + let foo: number = undefined/*Ωignore_startΩ*/;foo = __sveltets_2_any(foo);/*Ωignore_endΩ*/ + let foo2 = undefined + let clazz: string/*Ωignore_startΩ*/;clazz = __sveltets_2_any(clazz);/*Ωignore_endΩ*/ + + const bar: string = '' +; +async () => { { svelteHTML.createElement("svelte:options", {"accessors":true,});} +}; +return { props: {foo: foo , foo2: foo2 , class: clazz , bar: bar}, exports: /** @type {{foo: number,foo2: typeof foo2,class: string,bar: string}} */ ({}), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(['foo','foo2','bar'], __sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-mustachetag-false/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-mustachetag-false/expected-svelte5.ts new file mode 100644 index 000000000..b4b4db377 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-mustachetag-false/expected-svelte5.ts @@ -0,0 +1,12 @@ +/// +;function render() { + + let foo: number = undefined/*Ωignore_startΩ*/;foo = __sveltets_2_any(foo);/*Ωignore_endΩ*/ + const bar: string = '' +; +async () => { { svelteHTML.createElement("svelte:options", { "accessors":false,});} +}; +return { props: {foo: foo , bar: bar}, exports: /** @type {{bar: string}} */ ({}), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(['foo','bar'], __sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-mustachetag-true/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-mustachetag-true/expected-svelte5.ts new file mode 100644 index 000000000..52e8f1d49 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-mustachetag-true/expected-svelte5.ts @@ -0,0 +1,15 @@ +/// +;function render() { + + let foo: number = undefined/*Ωignore_startΩ*/;foo = __sveltets_2_any(foo);/*Ωignore_endΩ*/ + let foo2 = undefined + let clazz: string/*Ωignore_startΩ*/;clazz = __sveltets_2_any(clazz);/*Ωignore_endΩ*/ + + const bar: string = '' +; +async () => { { svelteHTML.createElement("svelte:options", { "accessors":true,});} +}; +return { props: {foo: foo , foo2: foo2 , class: clazz , bar: bar}, exports: /** @type {{foo: number,foo2: typeof foo2,class: string,bar: string}} */ ({}), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(['foo','foo2','bar'], __sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-no-svelte-options/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-no-svelte-options/expected-svelte5.ts new file mode 100644 index 000000000..c87f62582 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/uses-accessors-no-svelte-options/expected-svelte5.ts @@ -0,0 +1,11 @@ +/// +;function render() { + + let foo: number = undefined/*Ωignore_startΩ*/;foo = __sveltets_2_any(foo);/*Ωignore_endΩ*/ + const bar: string = '' +; +async () => {}; +return { props: {foo: foo , bar: bar}, exports: /** @type {{bar: string}} */ ({}), slots: {}, events: {} }} +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(['foo','bar'], __sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/uses-svelte-components-let-forward/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/uses-svelte-components-let-forward/expected-svelte5.ts index 3db0e6f76..c07eca3b0 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/uses-svelte-components-let-forward/expected-svelte5.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/uses-svelte-components-let-forward/expected-svelte5.ts @@ -10,6 +10,6 @@ async () => {if(true){ { __sveltets_createSlot("default", { prop,});} }}}; return { props: /** @type {Record} */ ({}), slots: {'default': {prop:__sveltets_2_instanceOf(__sveltets_1_componentType()).$$slot_def['default'].prop}}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component_slots(__sveltets_2_partial(__sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/uses-svelte-components/expected-svelte5.ts b/packages/svelte2tsx/test/svelte2tsx/samples/uses-svelte-components/expected-svelte5.ts index b5aa1f8cb..013879f90 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/uses-svelte-components/expected-svelte5.ts +++ b/packages/svelte2tsx/test/svelte2tsx/samples/uses-svelte-components/expected-svelte5.ts @@ -15,6 +15,6 @@ async () => {if(true){ { svelteHTML.createElement("svelte:fragment", {});} { svelteHTML.createElement("svelte:document", { "foo":`bar`,"on:click":e => {},});}}; return { props: /** @type {Record} */ ({}), slots: {}, events: {} }} - -export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) { -} \ No newline at end of file +const Input__SvelteComponent_ = __sveltets_2_isomorphic_component(__sveltets_2_partial(__sveltets_2_with_any_event(render()))); +/*Ωignore_startΩ*/type Input__SvelteComponent_ = InstanceType; +/*Ωignore_endΩ*/export default Input__SvelteComponent_; \ No newline at end of file