SvelteKit中通过setContext或组件属性传递自定义Store时如何设置类型?
解决SvelteKit中Store通过Context/Props传递的类型问题
这个问题的核心是getContext和未类型化的Props默认会丢失Store的具体类型,我们可以通过显式定义Store类型并在传递/获取时指定类型来解决,同时完全保留在路由页面创建Store的正确实践(避免服务器端单例问题)。
步骤1:定义Store的类型
首先,我们把自定义Store的类型抽出来(可以放在单独的types.ts文件里,或者直接在页面组件中定义),这样可以在多个组件中复用:
// src/routes/types.ts import type { Subscriber, Invalidator, Unsubscriber } from 'svelte/store'; export type CountStore = { subscribe: (run: Subscriber<number>, invalidate?: Invalidator<number>) => Unsubscriber; increment: () => void; decrement: () => void; reset: () => void; };
步骤2:在页面中创建Store并指定Context类型
在+page.svelte里,给createCount函数指定返回类型,同时在setContext时显式声明Context的类型:
<!-- src/routes/+page.svelte --> <script lang="ts"> import Child from "./Child.svelte"; import { writable } from 'svelte/store'; import { setContext } from "svelte"; import type { CountStore } from './types'; function createCount(): CountStore { 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(); // 显式指定Context的类型为CountStore setContext<CountStore>("store", count); </script> <Child />
步骤3:在子组件中获取带类型的Context
在Child.svelte里,使用getContext时指定我们定义的CountStore类型,这样TypeScript就能正确推断Store的所有方法和属性:
<!-- src/routes/Child.svelte --> <script lang="ts"> import { getContext } from "svelte"; import type { CountStore } from './types'; // 显式指定Context的类型,避免类型为any const count = getContext<CountStore>("store"); // 如果担心Context可能不存在,可以添加非空断言或处理null的情况: // const count = getContext<CountStore | null>("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>
针对Props传递的类型解决方案
如果是通过<Child {count}/>传递Store,只需要在子组件中给Props指定类型即可:
<!-- src/routes/Child.svelte --> <script lang="ts"> import type { CountStore } from './types'; // 给Props显式指定CountStore类型 export let count: CountStore; </script> <!-- 其余代码不变 -->
为什么这个方案可行?
- 我们始终在路由页面创建Store,避免了服务器端模块仅加载一次导致的单例问题,保证了每个请求/客户端都有独立的Store实例。
- 通过显式定义和指定类型,TypeScript可以准确推断Store的结构,解决了
any类型的问题。
内容的提问来源于stack exchange,提问作者lukaszpolowczyk
相关产品推荐
相关产品推荐

