Skip to content

Commit dddedf0

Browse files
authored
fix: generic const modifier (#2118)
#2107 Switching to let TypeScript parse the generic attribute by wrapping it with an arrow function.
1 parent fc538b6 commit dddedf0

File tree

4 files changed

+52
-3
lines changed

4 files changed

+52
-3
lines changed

packages/svelte2tsx/src/svelte2tsx/nodes/Generics.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,36 @@ export class Generics {
1414
this.genericsAttr = script.attributes.find((attr) => attr.name === 'generics');
1515
const generics = this.genericsAttr?.value[0]?.raw as string | undefined;
1616
if (generics) {
17-
this.definitions = generics.split(',').map((g) => g.trim());
18-
this.references = this.definitions.map((def) => def.split(/\s/)[0]);
17+
const typeParameters = this.getGenericTypeParameters(generics);
18+
19+
this.definitions = typeParameters?.map((param) => param.getText()) ?? [];
20+
this.references = typeParameters?.map((param) => param.name.getText()) ?? [];
1921
} else {
2022
this.genericsAttr = undefined;
2123
}
2224
}
2325

26+
private getGenericTypeParameters(rawGenericsAttr: string) {
27+
const sourceFile = ts.createSourceFile(
28+
'index.ts',
29+
`<${rawGenericsAttr}>() => {}`,
30+
ts.ScriptTarget.Latest,
31+
true
32+
);
33+
const firstStatement = sourceFile.statements[0];
34+
35+
if (!firstStatement || !ts.isExpressionStatement(firstStatement)) {
36+
return;
37+
}
38+
39+
const arrowFunction = firstStatement.expression;
40+
if (!ts.isArrowFunction(arrowFunction)) {
41+
return;
42+
}
43+
44+
return arrowFunction.typeParameters;
45+
}
46+
2447
addIfIsGeneric(node: ts.Node) {
2548
if (ts.isTypeAliasDeclaration(node) && this.is$$GenericType(node.type)) {
2649
if (this.genericsAttr) {

packages/svelte2tsx/test/helpers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function can_auto_update() {
1111
if (!process.argv.includes('--auto') && !all_tests_skipped) {
1212
if (update_count++ === 0) {
1313
process.on('exit', () => {
14-
const command = color.yellow('yarn run test --auto');
14+
const command = color.yellow('pnpm run test -- --auto');
1515
console.log(` Run ${command} to update ${update_count} files\n`);
1616
});
1717
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
///<reference types="svelte" />
2+
;function render<const T extends readonly string[]>() {
3+
4+
let items: T/*Ωignore_startΩ*/;items = __sveltets_2_any(items);/*Ωignore_endΩ*/;
5+
;
6+
async () => {};
7+
return { props: {items: items}, slots: {}, events: {} }}
8+
class __sveltets_Render<const T extends readonly string[]> {
9+
props() {
10+
return render<T>().props;
11+
}
12+
events() {
13+
return __sveltets_2_with_any_event(render<T>()).events;
14+
}
15+
slots() {
16+
return render<T>().slots;
17+
}
18+
}
19+
20+
21+
import { SvelteComponentTyped as __SvelteComponentTyped__ } from "svelte"
22+
export default class Input__SvelteComponent_<const T extends readonly string[]> extends __SvelteComponentTyped__<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> {
23+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<script lang="ts" generics="const T extends readonly string[]">
2+
export let items: T;
3+
</script>

0 commit comments

Comments
 (0)