Vue3 Pinia同Store内Getter方法互相调用报错求助
在Pinia选项式Store的Getter中调用另一个Getter的正确方法
问题场景
使用Vue3+TypeScript+Vuetify+组合式API开发,基于Pinia定义状态管理Store时,在同一Store的一个getter中调用另一个getter遇到两类错误:
- 直接调用
exMethodOne()提示「Cannot find name 'exMethodOne'」 - 添加
getters参数后调用出现类型不匹配的重载错误
代码示例
// ... imports export const useExampleStore = defineStore('example-store', { state: () => ({ report: { ...initialReport }, groups: { ...initialGroups }, } as ExStoreState), getters: { exMethodOne(state) { if (state.report.type != 'code' || !state.report.forceAdmin) { return formatParams(state.groups.selections); } else { return state.report.selection_codes; } }, exMethodTwo(state, getters) { const selectionCodes = getters.exMethodOne() // 此处触发错误 return { 'filters[selection_codes][]': selectionCodes, // ... 其他属性 } as any; }, }, actions: { // ... 动作方法 }, });
错误信息
添加getters参数后收到的报错:
No overload matches this call. Overload 1 of 3, '(id: "statements-report", options: Omit<DefineStoreOptions<"statements-report", SrsState, _GettersTree<SrsState>, { getLabelGroups(report: ReportType): Promise<...>; SongSearch(): Promise<...>; getUserStatemntsReport(values: StatementReportParams): Promise<...>; getStatement(values: StatementDownloadParams): Promise<...>; getAdminStatemntsReport(values: StatementReportParams): Promise<...>; }>, "id">): StoreDefinition<...>', gave the following error. Type '(state: any, getters: any) => any' is not assignable to type '(() => any) | ((state: SrsState & PiniaCustomStateProperties<SrsState>) => any)'. Type '(state: any, getters: any) => any' is not assignable to type '() => any'. Target signature provides too few arguments. Expected 2 or more, but got 0. Overload 2 of 3, '(id: "statements-report", storeSetup: () => unknown, options?: DefineSetupStoreOptions<"statements-report", _UnwrapAll<Pick<unknown, never>>, Pick<unknown, never>, Pick<unknown, never>> | undefined): StoreDefinition<...>', gave the following error. Argument of type '{ state: () => SrsState; getters: { accountNumber: () => string; resetReport(state: SrsState & PiniaCustomStateProperties<SrsState>): void; configureSongCodes(state: SrsState & PiniaCustomStateProperties<...>): any; filterSetter(state: any, getters: any): any; }; actions: { ...; }; }' is not assignable to parameter of type '() => unknown'. Object literal may only specify known properties, and 'state' does not exist in type '() => unknown'.
解决方案
在Pinia的选项式API中,getter的第二个参数getters是当前Store所有getter的集合,这些getter本质是Vue计算属性,不需要加括号调用,直接访问即可。同时需给getters指定正确类型,避免TypeScript报错。
修正后的代码
// ... imports import type { _GettersTree } from 'pinia'; // 定义Store的State类型 interface ExStoreState { report: typeof initialReport; groups: typeof initialGroups; } // 定义Getters类型 type ExStoreGetters = { exMethodOne: ReturnType<typeof formatParams> | typeof initialReport.selection_codes; exMethodTwo: { 'filters[selection_codes][]': ExStoreGetters['exMethodOne'] } & Record<string, any>; }; export const useExampleStore = defineStore('example-store', { state: () => ({ report: { ...initialReport }, groups: { ...initialGroups }, } as ExStoreState), getters: { exMethodOne(state): ExStoreGetters['exMethodOne'] { if (state.report.type != 'code' || !state.report.forceAdmin) { return formatParams(state.groups.selections); } else { return state.report.selection_codes; } }, // 给getters参数指定准确类型 exMethodTwo(state, getters: _GettersTree<ExStoreState> & ExStoreGetters): ExStoreGetters['exMethodTwo'] { // 直接访问getters.exMethodOne,无需加括号 const selectionCodes = getters.exMethodOne; return { 'filters[selection_codes][]': selectionCodes, // ... 其他属性 } as ExStoreGetters['exMethodTwo']; }, }, actions: { // ... 动作方法 }, });
关键说明
- 不要给getter加括号:Pinia的getter是计算属性,在
getters参数中访问时是已计算完成的值,而非函数,因此直接用getters.exMethodOne而非getters.exMethodOne()。 - 明确TypeScript类型:通过自定义
ExStoreGetters类型并结合Pinia提供的_GettersTree,给getters参数指定精确类型,解决类型不匹配问题。 - 若无需严格类型校验,可临时给
getters指定any类型,但推荐始终做好类型定义以发挥TypeScript的类型校验优势。
内容的提问来源于stack exchange,提问作者Sandisz Thieme
相关产品推荐
相关产品推荐

