$-prefix bug reproductionMinimal reproduction for a bug in [email protected] where the transformer's scan_store_subscriptions function misidentifies $-prefixed property accesses and callback parameter names as Svelte store references.
svelte-check-rs scans for $identifier patterns in script content and emits store alias declarations like let $from!: __StoreValue<typeof from>;. The scanner does not check whether the $ is preceded by a . (property access) or appears inside a callback parameter list. This causes it to generate spurious store aliases that reference non-existent variables, producing TS2552 and TS2304 errors.
$-prefixed property accessWhen a TypeScript interface has a $-prefixed property (e.g., ProseMirror's Selection.$from), accessing it like selection.$from.parent causes the scanner to treat from as a store name and emit let $from!: __StoreValue<typeof from>;, where from does not exist.
File: src/lib/DollarPropAccess.svelte
$-prefixed callback parameter namesWhen a callback uses a $-prefixed parameter name (e.g., items.map(($item) => $item * 2)), the scanner treats item as a store name and emits let $item!: __StoreValue<typeof item>;, where item does not exist.
Note: store.update(($form) => ...) does NOT produce an error because form (the store variable itself) IS in scope. The bug surfaces when the bare name has no corresponding variable declaration (e.g., $item, $val).
File: src/lib/DollarParamName.svelte
Expected: selection.$from should be treated as a property access on selection, not as a store subscription. Callback parameters like ($item) => ... should be recognized as local parameter names, not store references. No store aliases should be generated for these patterns.
Actual: The transformer emits spurious store aliases:
let $from!: __StoreValue<typeof from>; // 'from' does not exist in scope
let $to!: __StoreValue<typeof to>; // 'to' does not exist in scope
let $item!: __StoreValue<typeof item>; // 'item' does not exist in scope
let $val!: __StoreValue<typeof val>; // 'val' does not exist in scope
These produce TS2552 ("Cannot find name 'from'. Did you mean '$from'?") and TS2304 ("Cannot find name 'to'") errors when type-checked by tsc.
pnpm install
bash verify.sh
Or step by step:
# 1. See the incorrect transformed output (look for spurious store aliases)
pnpm check:rs:emit
# 2. Run svelte-check-rs (populates cache, uses tsgo -- may show 0 errors)
pnpm check:rs
# 3. Run legacy svelte-check for comparison (shows 0 errors)
pnpm check:legacy
# 4. Run tsc on svelte-check-rs's generated files to confirm the TS errors
CACHE_DIR=$(find node_modules/.cache/svelte-check-rs -maxdepth 1 -mindepth 1 -type d -not -name compiler-diagnostics | head -1)
npx tsc --noEmit --ignoreConfig --strict "$CACHE_DIR/src/lib/DollarPropAccess.svelte.ts"
npx tsc --noEmit --ignoreConfig --strict "$CACHE_DIR/src/lib/DollarParamName.svelte.ts"
The scan_store_subscriptions function in crates/svelte-transformer/src/runes.rs (line ~201) identifies $identifier patterns by looking for a $ character followed by an alphabetic character or underscore. It does not inspect the character preceding the $, so it cannot distinguish:
selection.$from (the $ follows a .)($item) => ... (the $ follows a ( or ,)$myStore (the $ is at the start of an expression)The same issue exists in transform_store_subscriptions_in_template in crates/svelte-transformer/src/template.rs (line ~305).
svelte-check-rs uses tsgo (Go-based TypeScript compiler) internally. As of tsgo v7.0.0-dev, it does not report TS2552/TS2304 for typeof undeclared_variable in type annotations, so the CLI output may appear clean despite the incorrect transform. The bug is confirmed by running standard tsc on the generated files, and the spurious aliases are always visible via --emit-ts.