You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建从方法参数推断类型且不随响应式变量销毁的自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 21:39:00