svelte-check-rs-repro-dollar-prefix Svelte Themes

Svelte Check Rs Repro Dollar Prefix

Minimal repro: svelte-check-rs misidentifies $-prefixed property accesses and callback params as Svelte store subscriptions

svelte-check-rs $-prefix bug reproduction

Minimal 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.

The Bug

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.

Pattern A: $-prefixed property access

When 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

Pattern B: $-prefixed callback parameter names

When 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 vs. Actual Behavior

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.

How to Reproduce

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"

Root Cause

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:

  • Property access: selection.$from (the $ follows a .)
  • Callback parameters: ($item) => ... (the $ follows a ( or ,)
  • Actual store subscriptions: $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).

Note on tsgo

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.

Versions

  • svelte-check-rs: 0.9.18
  • svelte-check: 4.4.8
  • svelte: 5.55.9
  • typescript: 6.0.3

Top categories

Loading Svelte Themes