使用JSDoc对Zustand切片模式进行类型检查的问题
使用JSDoc对Zustand切片模式进行类型检查的问题
大家好,我最近在尝试给Zustand官方文档里的切片模式示例添加JSDoc类型检查,过程中遇到了几个头疼的问题,折腾了一阵后终于搞定了,在这里跟大家分享下我的经历和解决办法:
最初的问题:切片模式下的类型检查与自动补全
我想要给切片模式的代码加上JSDoc类型注解,实现类型检查和组件中useBoundStore的自动补全,但遇到了两个核心问题:
- Zustand的
create函数类型没有导出,没法直接用它来标注类型 - 虽然用
StateCreator能实现部分类型提示,但加上devtools、immer这类中间件后,类型检查就会报错
先给大家看下我最初的代码(带JSDoc注解):
// @ts-check import { create } from 'zustand'; /** * @typedef {{ * bears: number, * addBear: () => void, * eatFish: () => void, * }} BearSlice * * @typedef {{ * fishes: number, * addFish: () => void, * }} FishSlice */ /** * @typedef {import('zustand').StateCreator<BearSlice & FishSlice, [], [], FishSlice>} FishSliceCreator * * @type {FishSliceCreator} */ export const createFishSlice = (set) => ({ fishes: 0, addFish: () => set((state) => ({ fishes: state.fishes + 1 })), }); /** * @typedef {import('zustand').StateCreator<BearSlice & FishSlice, [], [], BearSlice>} BearSliceCreator * * @type {BearSliceCreator} */ export const createBearSlice = (set) => ({ bears: 0, addBear: () => set((state) => ({ bears: state.bears + 1 })), eatFish: () => set((state) => ({ fishes: state.fishes - 1 })), }); /** * ??? 这里不知道怎么给useBoundStore加类型注解 */ export const useBoundStore = create((...a) => ({ ...createBearSlice(...a), ...createFishSlice(...a), }));
加中间件后的类型错误
当我尝试给代码加上devtools和immer中间件,并且更新了StateCreator的类型注解后,@ts-check开始报错:
/** * @typedef {import('zustand').StateCreator< * BearSlice & FishSlice, * [], * [["zustand/devtools", never], ["zustand/immer", never]], * FishSlice * >} FishSliceCreator */ /** * @typedef {import('zustand').StateCreator< * BearSlice & FishSlice, * [], * [["zustand/devtools", never], ["zustand/immer", never]], * BearSlice * >} BearSliceCreator */
最终的解决办法
折腾了半天后,我发现给中间件函数添加JSDoc类型注解就能解决这个问题。具体来说,给中间件的参数标注完整的StateCreator类型,就能让类型检查正常工作,同时也能保留自动补全功能:
/** * @param {import('zustand').StateCreator<BearSlice & FishSlice>} f */ const middleware = (f) => devtools(immer(f));
这样调整后,不仅@ts-check不再报错,组件里的useBoundStore也能正常获得自动补全了。
备注:内容来源于stack exchange,提问作者svelnoma
相关产品推荐
相关产品推荐

