TypeScript
包内自带声明,并扩展 Pinia-React 的 Store 选项。运行时导入插件会加载扩展;抽取配置的文件可以仅导入类型。不需要在应用中另建 pinia.d.ts 或手工扩充 Store。
内联回调推导完整 Store
优先把配置放在 defineStore 内部。恢复钩子和错误回调都能获得 State、Getter 结果与 Action 参数及返回值,策略数组内也一样:
counter.ts
import { defineStore } from 'pinia-react'
import '@pinia-react/persistedstate'
export const { getCounterStore, useCounterStore } = defineStore('counter', {
state: () => ({ count: 0, preferences: { theme: 'light' } }),
getters: { double: state => state.count * 2 },
actions: {
increment(amount: number) {
this.count += amount
return this.count
}
},
persist: {
pick: ['count', 'preferences.theme'],
afterHydrate({ store, options }) {
const doubled: number = store.double
const factoryCount: number = options.state().count
console.info(doubled, factoryCount)
},
onPersistError(error, store) {
const retryAction: (amount: number) => number = store.increment
console.warn(error.name, store.$id, typeof retryAction)
}
}
})
在 store. 后,编辑器应提示 count、preferences、double、increment 和核心 Store 成员。不存在的属性及错误的 Action 参数会报类型错误,而不是悄悄变成 any。生成的具名别名保持正常推导;$state 仍然只读。
导出的 PersistenceContext<State, StoreType> 描述 Store 级恢复上下文:store 是完整推导后的 Store,options.state() 和插件专用 restoreState 载荷保留 State 类型。restoreState 不是新的应用修改入口,业务代码仍使用 Action 和 $patch。
路径补全不是 schema 校验
StatePath<State> 为 pick / omit 提供点号分隔的普通对象路径建议:
- 包含可选、可空嵌套字段和联合类型各分支的成员。
- 数组和
Date 等特殊对象只提示整个字段,不提示数组下标、数组方法或实例方法路径。
- 递归类型的路径展开最多六段,避免编辑器无限展开。
- 不提示危险 key、空 key 或本身含点号的 key。
有意保留动态 string 路径支持,因此拼错的路径也可能通过编译,运行时不存在则被忽略。补全不是严格路径校验;TypeScript 和载荷形状校验也不验证业务 schema。宽泛字典无法列举未知运行时 key。即使提示了 Date 字段,也仍需选择合适的可持久化表示,不能据此推断可往返恢复或响应式支持。
抽取仅依赖 State 的配置
只访问 State 时使用 PersistenceOptions<State>:
extracted.ts
import { defineStore } from 'pinia-react'
import type { PersistenceOptions } from '@pinia-react/persistedstate'
interface PreferencesState {
theme: string
compact: boolean
}
const persistence: PersistenceOptions<PreferencesState> = {
pick: ['theme'],
afterHydrate({ store }) {
const theme: string = store.theme
console.info(theme)
}
}
export const preferences = defineStore('preferences', {
state: (): PreferencesState => ({ theme: 'light', compact: false }),
getters: { label: state => `${state.theme}:${state.compact}` },
persist: persistence
})
const label: string = preferences.getStore().label
void label
显式 State-only 配置的回调不知道 Getter / Action,但它不会抹掉最终 Store 自己的 Getter / Action 推导。
共享配置或工具已知完整 Store 类型时,可以提供第二个泛型:
typed-options.ts
import type { PersistenceOptions } from '@pinia-react/persistedstate'
import type { getCounterStore } from './counter'
type CounterStore = ReturnType<typeof getCounterStore>
export const counterPersistence: PersistenceOptions<CounterStore['$state'], CounterStore> = {
pick: ['preferences.theme'],
afterHydrate({ store }) {
const double: number = store.double
console.info(double)
},
onPersistError(_error, store) {
const increment: (amount: number) => number = store.increment
console.warn(store.$id, typeof increment)
}
}
这里复用的是前面已经定义的 counter.ts。不要用自身尚未完成推导的定义的返回类型标注该 Store 初始化器,否则会形成循环类型依赖。这种场景优先保留内联推导。
全局回调保持泛型
工厂服务于形状不同的多个 Store,无法推导某个特定 Store 的 Getter 或 Action 名称:
global.ts
import { createPersistedState, type PluginOptions } from '@pinia-react/persistedstate'
const options: PluginOptions = {
afterHydrate({ store }) { console.info(store.$id) },
onPersistError(error, store) { console.warn(error.name, store.$id) }
}
export const persistence = createPersistedState(options)
全局回调适合跨 Store 行为和元信息。依赖具体形状的逻辑应放入 Store 自己的回调,不要把全局泛型 Store 强行断言成某个具体 Store。
可选的手动方法
公开 Store 类型上的 $hydrate / $persist 都是可选的,即使 persist: true 也一样。模块扩展还会影响未启用持久化和未注册插件的 Store,声明为必有方法会作出不安全的承诺。
methods.ts
import { getCounterStore } from './counter'
const counter = getCounterStore()
counter.$hydrate?.({ runHooks: false })
counter.$persist?.()
if (counter.$persist) counter.$persist()
不要用非空断言掩盖漏注册。导入类型只启用配置类型,不会安装运行时插件;仍需像快速入门那样在创建 Store 前注册。
公开类型
| 类型 |
用途 |
StorageLike |
同步 getItem / setItem 适配器 |
Serializer |
同步快照序列化器,输入不一定是完整 State |
PersistenceOptions<S, StoreType> |
单策略,可仅推导 State 或完整 Store |
PersistenceContext<S, StoreType> |
Store 级恢复钩子上下文 |
Persist<S, StoreType> |
布尔值、单策略或只读策略数组联合 |
PluginOptions |
工厂默认值、全局回调、key 转换及 auto |
HydrateOptions |
手动恢复的 runHooks 选项 |
StatePath<S> |
State 路径建议,不是严格校验 schema |
Next.js Cookie 入口
@pinia-react/persistedstate/next 导出 createCookiePersistedState、readCookieSnapshot、CookieSnapshot、CookieReader、CookieOptions 和 CookiePersistenceOptions,并加载同一份 Store 选项扩展。Cookie 工厂要求显式请求快照,提供 Cookie 属性补全,不接受其他工厂 storage 或 HttpOnly 选项。内联 Store 回调保留上面的推导,完整示例见 Next.js 接入。