Skip to content

Svelte 5: using var with $state is brittle #12807

@Rich-Harris

Description

@Rich-Harris

Describe the bug

State declarations are transformed thusly:

-let count = $state(0);
+let count = $.source(0);

If we tried to console.log(count) before the declaration, we would get a TDZ error:

Can't access lexical declaration 'count' before initialization

But if it's a var instead, we don't — instead we try to get(undefined).

-console.log(count);
+console.log($.get(count));

This errors with

signal is undefined

which is cryptic and unhelpful.

Possible remedies:

  1. add a if (signal === undefined) return signal to the top of get
    /**
    * @template V
    * @param {Value<V>} signal
    * @returns {V}
    */
    export function get(signal) {
    var flags = signal.f;
    if ((flags & DESTROYED) !== 0) {
    return signal.v;
    }
  2. disallow var
  3. hoist the declaration

Option 1 means doing a tiny bit of extra work on every get for something that's a real edge case. Option 2 feels like a bit of a cop-out. So I think we should probably do option 3.

Reproduction

link

Logs

No response

System Info

next

Severity

annoyance

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions