[英]How do I set the type, for custom store, when I pass store via setContext or component prop?
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.使用 SvelteKit 时,必须始终在 route
page
/ layout
中创建store
,否则会出现刷新后状态为 up-to-date 的问题。
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
.您不能在导入的模块中创建
store
,因为服务器端模块只加载一次,这会导致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
:我通过
setContext
创建并将商店从+page.svelte
到Child.svelte
:
<!-- +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
:在
Child.svelte
中, store
计数的类型是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"):这应该是
store
的类型,从 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.通过
<Child {count}/>
传递有同样的问题。
QUESTION: How can this be done?问题:如何做到这一点?
It doesn't.它没有。 You can only create a
store
in a module, and import it - then the types are preserved.您只能在模块中创建
store
并导入它 - 然后类型被保留。
But this creates some problems with store
validity, as I wrote about at the beginning.但这会在
store
有效性方面产生一些问题,正如我在开头所写的那样。
There are two primary options: Use preprocess-svelte
and write TypeScript or add JSDoc type annotations.有两个主要选项:使用
preprocess-svelte
并编写 TypeScript 或添加 JSDoc 类型注释。
With TS:使用 TS:
<script lang="ts">
import { getContext } from 'svelte';
// Prop
export let count: StoreType;
// Context
const store = getContext<StoreType>('context');
</script>
With JSDoc:使用 JSDoc:
<script>
import { getContext } from 'svelte';
// Prop
/** @type {StoreType} */
export let count;
// Context
/** @type {StoreType} */
const store = getContext('context');
</script>
You can declare types in separate .d.ts
files or use @typedef
.您可以在单独的
.d.ts
文件中声明类型或使用@typedef
。
The createCount
function can be extracted to a separate file without issue. createCount
function 可以毫无问题地提取到单独的文件中。 That way its return type can also be used when typing props/contexts.这样,在输入道具/上下文时也可以使用它的返回类型。 Eg
例如
// create-count.js
import { writable } from 'svelte/store';
export function createCount() {
const { subscribe, set, update } = writable(0);
return {
subscribe,
increment: () => update(n => n + 1),
decrement: () => update(n => n - 1),
reset: () => set(0),
};
}
<script>
import { getContext } from 'svelte';
/** @type {ReturnType<import('./create-count').createCount>} */
export let count;
/** @type {ReturnType<import('./create-count').createCount>} */
const store = getContext('context');
</script>
In TS this is cleaner, since you can just import the type as part of regular code and use type aliases.在 TS 中这更简洁,因为您可以将类型作为常规代码的一部分导入并使用类型别名。
<script lang="ts">
import type { createCount } from './create-count';
import { getContext } from 'svelte';
export let count: Count;
const store = getContext<Count>('context');
type Count = ReturnType<typeof createCount>;
</script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.