如何创建从方法参数推断类型且不随响应式变量销毁的自定义Svelte store
实现方案
修改store.ts逻辑
调整store的类型定义和返回逻辑,支持通过方法参数自动推导泛型,同时保证store实例全局唯一:
import { writable, type Writable } from "svelte/store"; // 定义store实例类型,泛型默认未知,后续通过方法参数推断 interface StoreInstance<T = unknown> { subscribe: Writable<T>["subscribe"]; // 方法接收泛型参数,返回匹配类型的实例本身 changePlayer: <U extends T>(player: U) => StoreInstance<U>; } export function useStore(): StoreInstance { // 仅初始化一次store实例 const store = writable<unknown>(); const changePlayer = (player: unknown) => { store.set({ ...player }); // 返回当前实例,自动继承入参的类型 return instance as StoreInstance<typeof player>; }; const instance: StoreInstance = { subscribe: store.subscribe, changePlayer }; return instance; }
调整App.svelte写法
将store初始化和响应式更新拆分,避免响应式触发时重建store,同时完成自动类型推断:
<script lang="ts"> import { useStore } from "./store"; interface Player { name: string; } const player = { name: "Bob" }; const handleChange = () => { player.name = player.name === "Bob" ? "John" : "Bob"; }; // 组件初始化时仅创建一次store,不会重复销毁重建 const baseStore = useStore(); // 响应式调用更新方法,自动推断store的泛型为Player类型 $: game = baseStore.changePlayer(player); </script> <button on:click={handleChange}>Change player</button> {JSON.stringify($game)}
核心逻辑说明
- 类型自动推断:
changePlayer被定义为泛型方法,调用时会根据传入参数的类型自动推导泛型值,不需要在调用useStore时手动指定类型 - 避免store销毁:store实例的初始化放在顶层脚本,仅在组件首次加载时执行一次,响应式语句中仅调用更新方法修改状态,不会触发store重建,原有订阅和状态都会正常保留
内容的提问来源于stack exchange,提问作者Fred Hors
相关产品推荐
相关产品推荐

