Zustand中三元切换中间件触发TypeScript类型错误求助
修复Zustand中三元运算符切换中间件导致的TypeScript类型不兼容问题
问题核心是三元运算符两端的StateCreator类型因中间件数量不同,导致内部$$storeMutators属性的元组长度不匹配,触发TS2345错误。以下是几种可行的修复方案:
方案1:显式类型断言统一类型
将三元运算符两端的结果断言为包含所有可能中间件标识的StateCreator类型,强制TypeScript忽略元组长度差异:
import { create, StateCreator } from 'zustand'; import { devtools, immer } from 'zustand/middleware'; type State = { count: number; increment: () => void; }; const baseStore: StateCreator<State, [], []> = (set) => ({ count: 0, increment: () => set((state) => { state.count++; }) }); const USE_DEV_TOOLS_FOR_STORE = true; // 断言为包含devtools和immer标识的StateCreator类型 const useStore = create( USE_DEV_TOOLS_FOR_STORE ? devtools(immer(baseStore)) as StateCreator<State, [["zustand/devtools", never], ["zustand/immer", never]]> : immer(baseStore) as StateCreator<State, [["zustand/devtools", never], ["zustand/immer", never]]> );
方案2:统一中间件链结构
通过一个空中间件(noop)保持两边的中间件层级一致,让TypeScript推断出相同的类型:
import { create, StateCreator } from 'zustand'; import { devtools, immer } from 'zustand/middleware'; type State = { count: number; increment: () => void; }; const baseStore: StateCreator<State, [], []> = (set) => ({ count: 0, increment: () => set((state) => { state.count++; }) }); const USE_DEV_TOOLS_FOR_STORE = true; // 定义空的devtools替代中间件 const noopDevtools = <T>(config: StateCreator<T>) => config; // 无论开关状态,中间件链都是两层,类型自动对齐 const useStore = create( (USE_DEV_TOOLS_FOR_STORE ? devtools : noopDevtools)(immer(baseStore)) );
方案3:用if-else替代三元表达式
TypeScript对if-else分支的类型推断更宽松,不会强制要求分支结果类型完全一致,因此可以拆分创建逻辑:
import { create } from 'zustand'; import { devtools, immer } from 'zustand/middleware'; type State = { count: number; increment: () => void; }; const baseStore = (set) => ({ count: 0, increment: () => set((state) => { state.count++; }) }); const USE_DEV_TOOLS_FOR_STORE = true; let useStore; if (USE_DEV_TOOLS_FOR_STORE) { useStore = create(devtools(immer(baseStore))); } else { useStore = create(immer(baseStore)); } // 若需保持const声明,可提前指定类型 const useStore: ReturnType<typeof create> = USE_DEV_TOOLS_FOR_STORE ? create(devtools(immer(baseStore))) : create(immer(baseStore));
原因说明
Zustand的中间件会通过$$storeMutators元组标记使用的中间件类型,devtools(immer(store))的元组包含两个元素,而immer(store)仅包含一个。三元运算符要求两端类型严格匹配,因此触发类型错误。上述方案通过类型对齐或避免强制类型匹配的场景解决问题。
内容的提问来源于stack exchange,提问作者Pantaiz
相关产品推荐
相关产品推荐

