Skip to content

Commit bdfa37a

Browse files
fix: snippets with TS incorrect transformation (#2412)
After sveltejs/svelte#12070 the AST for the SnippetBlock has changed (to be more correct). The problem is that svelte2tsx was using that wrong information for the transformation. This means that currently last version of svelte produces wrong ts code from svelte2tsx.
1 parent be5e535 commit bdfa37a

File tree

4 files changed

+34
-15
lines changed

4 files changed

+34
-15
lines changed

packages/svelte2tsx/src/htmlxtojsx_v2/nodes/SnippetBlock.ts

+20-11
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,20 @@ export function handleSnippet(
4242
}
4343
);
4444

45+
const lastParameter = snippetBlock.parameters?.at(-1);
46+
4547
const startEnd =
4648
str.original.indexOf(
4749
'}',
48-
// context was the first iteration in a .next release, remove at some point
49-
snippetBlock.parameters?.at(-1)?.end || snippetBlock.expression.end
50+
lastParameter?.typeAnnotation?.end ?? lastParameter?.end ?? snippetBlock.expression.end
5051
) + 1;
5152

5253
if (isImplicitProp) {
5354
str.overwrite(snippetBlock.start, snippetBlock.expression.start, '', { contentOnly: true });
5455
const transforms: TransformationArray = ['('];
5556
if (snippetBlock.parameters?.length) {
56-
const start = snippetBlock.parameters?.[0].start;
57-
const end = snippetBlock.parameters.at(-1).end;
57+
const start = snippetBlock.parameters[0].start;
58+
const end = lastParameter.typeAnnotation?.end ?? lastParameter.end;
5859
transforms.push([start, end]);
5960
str.overwrite(snippetBlock.expression.end, start, '', {
6061
contentOnly: true
@@ -73,15 +74,23 @@ export function handleSnippet(
7374
let generic = '';
7475
if (snippetBlock.parameters?.length) {
7576
generic = `<[${snippetBlock.parameters
76-
.map((p) =>
77-
p.typeAnnotation?.typeAnnotation
77+
.map((p) => {
78+
let typeAnnotation = p.typeAnnotation;
79+
if (!typeAnnotation && p.type === 'AssignmentPattern') {
80+
typeAnnotation = p.left?.typeAnnotation;
81+
if (!typeAnnotation) {
82+
typeAnnotation = p.right?.typeAnnotation;
83+
}
84+
}
85+
if (!typeAnnotation) return 'any';
86+
return typeAnnotation.typeAnnotation
7887
? str.original.slice(
79-
p.typeAnnotation.typeAnnotation.start,
80-
p.typeAnnotation.typeAnnotation.end
88+
typeAnnotation.typeAnnotation.start,
89+
typeAnnotation.typeAnnotation.end
8190
)
8291
: // slap any on to it to silence "implicit any" errors; JSDoc people can't add types to snippets
83-
'any'
84-
)
92+
'any';
93+
})
8594
.join(', ')}]>`;
8695
}
8796

@@ -94,7 +103,7 @@ export function handleSnippet(
94103

95104
if (snippetBlock.parameters?.length) {
96105
const start = snippetBlock.parameters[0].start;
97-
const end = snippetBlock.parameters.at(-1).end;
106+
const end = lastParameter.typeAnnotation?.end ?? lastParameter.end;
98107
transforms.push([start, end]);
99108
}
100109

packages/svelte2tsx/test/helpers.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -320,12 +320,16 @@ export function test_samples(dir: string, transform: TransformSampleFn, js: 'js'
320320
try {
321321
assert.strictEqual(actual, expected, TestError.WrongExpected);
322322
} catch (e) {
323+
// html2jsx tests don't have the default export
324+
const expectDefaultExportPosition = expected.lastIndexOf(
325+
'\n\nexport default class'
326+
);
327+
if (expectDefaultExportPosition === -1) {
328+
throw e;
329+
}
323330
// retry with the last part (the returned default export) stripped because it's always differing between old and new,
324331
// and if that fails then we're going to rethrow the original error
325-
const expectedModified = expected.substring(
326-
0,
327-
expected.lastIndexOf('\n\nexport default class')
328-
);
332+
const expectedModified = expected.substring(0, expectDefaultExportPosition);
329333
const actualModified = actual.substring(0, actual.lastIndexOf('\nconst '));
330334
try {
331335
assert.strictEqual(

packages/svelte2tsx/test/htmlx2jsx/samples/ts-in-template.v5/expectedv2.js

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ item as string;
2424

2525
var foo3/*Ωignore_startΩ*/: import('svelte').Snippet<[string | number, (str: string)=>void]>/*Ωignore_endΩ*/ = (bar : string | number, baz : (str: string)=>void) => {async () => { };return __sveltets_2_any(0)};
2626

27+
var foo3/*Ωignore_startΩ*/: import('svelte').Snippet<[{baz: string}]>/*Ωignore_endΩ*/ = (bar: {baz: string}) => {async () => { };return __sveltets_2_any(0)};
28+
2729
;__sveltets_2_ensureSnippet(foo(bar as string));
2830

2931
{ svelteHTML.createElement("button", { "onclick":(e: Event) => {e as any},}); }

packages/svelte2tsx/test/htmlx2jsx/samples/ts-in-template.v5/input.svelte

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
snippet
3939
{/snippet}
4040

41+
{#snippet foo3(bar: {baz: string})}
42+
snippet
43+
{/snippet}
44+
4145
{@render foo(bar as string)}
4246

4347
<button onclick={(e: Event) => {e as any}}>click</button>

0 commit comments

Comments
 (0)