I have a filter variable of type "all" | "active" | "completed"
, which I initialize to 'all'
(in fact it's reactive, declared with $state('all')
but I can reproduce the issue with a plain variable
so this works OK:
let filter: "all" | "active" | "completed" = "all"; // same thing happens if I use $state("all") function filteredFn() { console.log({ filter }); // => (property) filter: "all" | "active" | "completed" if (filter === "active") return todos.filter((t) => !t.completed); // OK! if (filter === "completed") return todos.filter((t) => t.completed); //OK! return todos; }
but if I try to do the same in side a $derived.by()
rune, filter is assumed to be of type 'all' as if it were declared with as const
, like this:
let filter: "all" | "active" | "completed" = "all"; let filtered = $derived.by(() => { console.log({ filter }); // => (property) filter: "all" !!!! WRONG!!! if (filter === "active") return todos.filter((t) => !t.completed); // This comparison appears to be unintentional because the types '"all"' and '"active"' have no overlap.ts(2367) if (filter === "completed") return todos.filter((t) => t.completed); // This comparison appears to be unintentional because the types '"all"' and '"completed"' have no overlap.ts(2367) return todos; });
I can fix it with:
let filter = "all" as "all" | "active" | "completed";
or with the $state rune:
let filter = $state<"all" | "active" | "completed">("all");
but I don't know why it doesn't work the same way it works with regular functions
It this a bug or am I missing something???