I don't know how to reproduce the following in the svelte-5 REPL because it doesn't recognize enum
from the same file:
<script lang="ts">
enum Pro {
ZERO,
ONE,
TWO
}
let pros: Pro = $state(Pro.ZERO);
const again: boolean = $derived(pros == Pro.ONE || pros == Pro.TWO);
</script>
I'm getting the typescript error:
This comparison appears to be unintentional because the types
Pro.IDLE
andPro.ONE
have no overlap. ts(2367)
Why?
$state
is generic, it takes the type of its argument. Since the argument is Pro.ZERO
and the declarations of pros
and again
are executed in the same scope without other assignments to pros
, the type for the variable is narrowed via control flow analysis from Pro
to Pro.ZERO
.
TS does not know that the derived re-evaluates later with a potentially different value of pros
.
You could either avoid the narrowing via $derived.by
or force the type to be less specific via a type assertion.
let pros = $state(Pro.ZERO) as Pro;
// or
let again = $derived.by(() => pros == Pro.ONE || pros == Pro.TWO);
($derived.by
works because now the comparison is in a function and TS cannot infer when the function will be called and hence what value pros
will have at that point in time.)