Pinia 与 TypeScript:类型与工程化
Pinia 的一大卖点是 TS 友好。这篇不罗列每个泛型参数,而是讲清楚:类型从哪里来、store 怎么标、常见报错怎么理解,以及和 自动导入 一起用时要注意什么。
类型信息从哪来
大致三层:
- state 的形状 决定 store 的核心类型;
- getters 推断为
ComputedRef或派生类型; - actions 就是普通异步函数的类型。
defineStore 在多数场景下能 推断 出不少东西;复杂场景再显式补泛型或 return type。
Options Store 与 Setup Store 的差异点
- Options API 风格:
state用函数返回初始对象,类型从返回值推断; - Setup Store:你自己
ref/computed,类型跟着走,灵活但有时要 多写一点标注。
团队若统一 setup store,TS 与运行时心智更一致;若维护老代码,Options 也要会读。
在组件里用 store 时的类型体验
useXxxStore()的返回值一般能带出 整棵 store 类型;- 和
storeToRefs搭配时,注意 解构后的 ref 类型 仍应正确。
若出现 any:
- 检查是否 路径别名、自动导入 没把类型带进来;
- 检查 store 是否 循环依赖 导致推断失败。
与 import type、模块导出
工程里常见做法:
- store 文件 默认导出
useXxxStore; - 需要时 额外导出类型(如
Store类型别名)给非组件模块用。
避免:
- 到处 重复声明 一份与 state 不同步的 interface。
小结:类型是契约,和 store 边界一起设计
- 优先让 state 形状 成为单一真相,再派生 getter/action 类型;
- setup store 与 Options store 的 TS 写法略有不同,团队统一风格更省事;
- 出现
any时先查 工具链与循环依赖,不要先怪 Pinia。
最后一篇讲 测试与 DevTools。