Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Svelte 5: Remove undefined from $state type? #11466

Open
brunnerh opened this issue May 4, 2024 · 2 comments
Open

Svelte 5: Remove undefined from $state type? #11466

brunnerh opened this issue May 4, 2024 · 2 comments

Comments

@brunnerh
Copy link
Member

brunnerh commented May 4, 2024

Describe the problem

Use of $state in classes may necessitate that no initial value is set as that is provided via the constructor.
The current typing will then force undefined to be part of the type which can lead to errors.

// (in class)
value = $state(); // => type is unknown
value = $state<number>(); // type is number | undefined, causing errors elsewhere
value: number = $state(); // E: "Type 'number | undefined' is not assignable to type 'number'."

Workaround:

value: number = $state() as any;

Describe the proposed solution

Potentially change type to something like:

declare function $state<T = any>(initial?: T): T;

The obvious downside is that this is less correct and could lead to errors, though $state declarations without value should be relatively rare.

#11455 would also address the problem by not requiring $state to be used without the initial value.

Importance

nice to have

@rChaoz
Copy link
Contributor

rChaoz commented May 4, 2024

I definitely do agree with this one - this is how state works in most frameworks, and even how it worked before with normal let declarations. Especially useful when having to interact with the DOM directly:

<script lang="ts">
    let self = $state<HTMLDivElement>()

    function onclick(e: MouseEvent) {
        // self can't be undefined here, but the type is HTMLDivElement | undefined
        self.doSomething()
    }
</script>

<div bind:this={self} {onclick}>...</div>

I would say most people are used to writing something like the code above, regardless of framework, without any typing issues.

@7nik
Copy link

7nik commented May 4, 2024

<script lang="ts">
    let self = $state<HTMLDivElement>()

    function onclick(e: MouseEvent) {
        // self can't be undefined here, but the type is HTMLDivElement | undefined
        self.doSomething()
    }

    self.doSomething(); // error - `self` is undefined
    onclick(); // error - `self` is undefined
</script>

<div bind:this={self} {onclick}>...</div>

People will make such mistakes because they are new to JS, doing it in a long file, being tired, editing unfamiliar code or code they haven't touched for months, etc. But with the current typing, TS will warn you. And you can always do if (!self) return; or self!.doSomething() to pass the error.

It's possible to achieve uninitialized states in classes, but for now, all the cases I make up are related to bad coding. I'd wait for #11455 and decide what to do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants