When using SvelteKit, the store
must always be created in the route page
/layout
, otherwise there will be problems with the status being up-to-date after refreshing.
You can't create a store
in an imported module, because the server-side module only loads once, and this causes errors in the store
.
All this leads to a certain situation with types.
The problem:
I create and pass the store from +page.svelte
to Child.svelte
, via setContext
:
<!-- +page.svelte -->
<script>
import Child from "./Child.svelte";
import { writable } from 'svelte/store';
import { setContext } from "svelte";
function createCount() {
/** @type {import("svelte/store").Writable<number>} */
const { subscribe, set, update } = writable(0);
return {
subscribe,
increment: () => update(n => n + 1),
decrement: () => update(n => n - 1),
reset: () => set(0)
};
}
export const count = createCount();
setContext("store", count);
</script>
<Child/>
<!-- Child.svelte -->
<script>
import { getContext } from "svelte";
const count = getContext("store");
</script>
<h1>The count is {$count}</h1>
<button on:click={count.increment}>+</button>
<button on:click={count.decrement}>-</button>
<button on:click={count.reset}>reset</button>
In Child.svelte
the type for store
count is any
:
And it should be as in the place of the declaration:
That's what it should be the type of store
, returned from getContext("store"):
const count: {
subscribe: (this: void, run: Subscriber<number>, invalidate?: Invalidator<number> | undefined) => Unsubscriber;
increment: () => void;
decrement: () => void;
reset: () => void;
}
Passing via <Child {count}/>
has the same problem.
QUESTION: How can this be done?
Alternative
It doesn't. You can only create a store
in a module, and import it - then the types are preserved.
But this creates some problems with store
validity, as I wrote about at the beginning.