You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -88,13 +91,13 @@ Parse the following virtual script code as a script:
88
91
```ts
89
92
90
93
const array = [1, 2, 3]
91
-
;
94
+
;function $_render1(){
92
95
93
-
94
-
95
-
96
-
97
-
Array.from(array).forEach((e)=>{const ee =e*2;(ee);});
96
+
Array.from(array).forEach((e) => {
97
+
const ee =e*2;
98
+
(ee);
99
+
});
100
+
}
98
101
```
99
102
100
103
This ensures that the variable `e` defined by `{#each}` is correctly scoped only within `{#each}`.
@@ -111,3 +114,58 @@ You can also check the results [Online DEMO](https://ota-meshi.github.io/svelte-
111
114
ESLint custom parsers that provide their own AST require `visitorKeys` to properly traverse the node.
112
115
113
116
See https://eslint.org/docs/latest/developer-guide/working-with-custom-parsers.
117
+
118
+
## Scope Types
119
+
120
+
TypeScript's type inference is pretty good, so parsing Svelte as-is gives some wrong type information.
121
+
122
+
e.g.
123
+
124
+
```ts
125
+
exportlet foo: { bar:number } |null=null
126
+
127
+
$: console.log(foo&&foo.bar);
128
+
// ^ never type
129
+
```
130
+
131
+
(You can see it on [TypeScript Online Playground](https://www.typescriptlang.org/play?#code/KYDwDg9gTgLgBAG2PAZhCAuOBvOAjAQyiwDsBXAWz2CjgF84AfOchBOAXhbLYFgAoAQBIsAYwgkAzhCQA6BBADmACjQQ4AMg1w1swlACUAbgFwz5i5YsB6a3AB6LYADcacGAE8wwAUA))
132
+
133
+
In the above code, foo in `$:` should be `object` or `null` in `*.svelte`, but TypeScript infers that it is `null` only.
134
+
135
+
To avoid this problem, the parser generates virtual code and traps statements within `$:` to function scope.
136
+
Then restore it to have the correct AST and ScopeManager.
137
+
138
+
For example:
139
+
140
+
```svelte
141
+
<script lang="ts">
142
+
export let foo: { bar: number } | null = null
143
+
144
+
$: console.log(foo && foo.bar);
145
+
146
+
$: r = foo && foo.bar;
147
+
148
+
$: ({ bar: n } = foo || { bar: 42 });
149
+
</script>
150
+
151
+
{foo && foo.bar}
152
+
```
153
+
154
+
Parse the following virtual script code as a script:
155
+
156
+
```ts
157
+
158
+
exportlet foo: { bar:number } |null=null
159
+
160
+
$: function $_reactiveStatementScopeFunction1(){console.log(foo&&foo.bar);}
161
+
162
+
$: let r =$_reactiveVariableScopeFunction2();
163
+
function $_reactiveVariableScopeFunction2(){returnfoo&&foo.bar;}
164
+
165
+
$: let { bar: n } =$_reactiveVariableScopeFunction3();
166
+
function $_reactiveVariableScopeFunction3(){returnfoo|| { bar: 42 };}
0 commit comments