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

$derived not playing nice with TypeScript's narrowing #14319

Closed
HoldYourWaffle opened this issue Nov 15, 2024 · 2 comments
Closed

$derived not playing nice with TypeScript's narrowing #14319

HoldYourWaffle opened this issue Nov 15, 2024 · 2 comments

Comments

@HoldYourWaffle
Copy link
Contributor

HoldYourWaffle commented Nov 15, 2024

Describe the bug

Take the following (contrived) example:

<script lang="ts">
    let value: string | null = $state(null);
    let upper = $derived(value?.toUpperCase());

    // ...value is mutated somewhere else...     
</script>

This works at runtime, but TypeScript complains about value being of type never inside $derived.
I can see why it thinks that: value is not reassigned before line 3, therefore it's narrowed to type null, therefore the not-null case never happens.
However, with Svelte's $derived this expression will be run again when value is set to a non-null value, so this narrowing is incorrect.

There seems to be no mention of this in the documentation or tutorial. Some helpful people in the Discord suspect this is a bug.

The callback mechanism of $derived.by doesn't trigger these shenanigans:

let value: string | null = $state(null);
let upper = $derived.by(() => value?.toUpperCase());

@CaptainCodeman also suggested this workaround which seems to trick TS into not narrowing down the type in mysterious ways:

let value = $state<string | null>(null);
let upper = $derived(value?.toUpperCase());

Reproduction

Since the playground doesn't show TS errors: repro-svelte-14319

Logs

No response

System Info

System:
    OS: Windows 10 10.0.19045
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 17.94 GB / 31.81 GB
  Binaries:
    Node: 20.18.0 - C:\Program Files\nodejs\node.EXE
    npm: 10.9.0 - C:\Program Files\nodejs\npm.CMD
    pnpm: 8.9.2 - ~\AppData\Local\pnpm\pnpm.EXE
  Browsers:
    Edge: Chromium (127.0.2651.74)
    Internet Explorer: 11.0.19041.4355
  npmPackages:
    svelte: ^5.0.0 => 5.2.0

Severity

annoyance

@brunnerh
Copy link
Member

brunnerh commented Nov 15, 2024

Duplicate of:

Can someone please move that first issue already (or maybe close it in favor of this or the language tools one, which would at least be in the most relevant spot).

@dummdidumm dummdidumm closed this as not planned Won't fix, can't repro, duplicate, stale Nov 15, 2024
@HoldYourWaffle
Copy link
Contributor Author

HoldYourWaffle commented Nov 15, 2024

Whoops, you're right. Looks like I'm not the first to forget checking all repositories 😛

I suspect this should be in language-tools, but I'll leave this open for someone more qualified to make that decision.

Edit: doh, I got race condition'ed...

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