如何为Pinia的useStore泛型指定类型以约束store属性?
实现带泛型约束的Pinia Auth Store
问题背景
我有一个用于存储当前登录用户profile的auth store,profile的类型是StaffProfile | ClientProfile | null的联合类型。部分组件仅允许StaffProfile类型的用户访问,希望通过给useAuthStore传入泛型参数,让这类场景下的profile属性被特定类型约束。
当前Store结构
interface State { profile: StaffProfile | ClientProfile | null } export const useAuthStore = defineStore('auth', { state: () : State => ({ profile: null, }), // ... 其他方法/属性 });
现有解决方案(类型断言)
目前可以通过类型断言达到目的,但不够优雅:
const authStore = useAuthStore(); const profile = authStore.profile as StaffProfile; // authStore.profile 类型为 StaffProfile | ClientProfile | null // profile 类型为 StaffProfile
理想实现方式
希望能通过泛型参数直接约束store的profile类型:
const authStore = useAuthStore<StaffProfile>(); // authStore.profile 类型为 StaffProfile
实现方案
修改useAuthStore的定义,让它支持泛型参数,同时限制泛型参数为合法的profile类型,避免传入无效值:
方式一:类型断言包装
import { defineStore } from 'pinia'; type ProfileType = StaffProfile | ClientProfile | null; export const useAuthStore = defineStore('auth', { state: () => ({ profile: null, }), // ... 其他方法/属性 }) as <T extends ProfileType = ProfileType>() => ReturnType<typeof defineStore<'auth', { state: () => ({ profile: T }); }>>;
方式二:函数封装泛型
import { defineStore } from 'pinia'; type ProfileType = StaffProfile | ClientProfile | null; export function useAuthStore<T extends ProfileType = ProfileType>() { return defineStore('auth', { state: () => ({ profile: null as T, }), // ... 其他方法/属性 })(); }
类型安全的动作方法
如果store包含修改profile的动作,同步调整参数类型确保类型安全:
export function useAuthStore<T extends ProfileType = ProfileType>() { return defineStore('auth', { state: () => ({ profile: null as T, }), actions: { setProfile(profile: T) { this.profile = profile; }, }, })(); }
使用效果
- 默认调用
useAuthStore()时,profile类型保持StaffProfile | ClientProfile | null - 传入泛型
useAuthStore<StaffProfile>()时,profile类型被约束为StaffProfile - 传入
useAuthStore<ClientProfile>()或useAuthStore<null>()也能正常工作
内容的提问来源于stack exchange,提问作者aron.duby
相关产品推荐
相关产品推荐

