我有一家简单的商店
interface CartState {
cart: { [id: string]: CartDto };
addItem: ({ id, image, name, price }: Omit<CartDto, "quantity">) => void;
removeItem: (id: string) => void;
reset: () => void;
}
export const useCart = create<CartState>((set, get) => ({
cart: {},
addItem: ({ id, image, name, price }) => {
set(() => {
const cart = get().cart;
if (!cart[id]) {
cart[id] = {
id,
image,
name,
price,
quantity: 0
};
}
cart[id].quantity += 1;
return { cart };
});
},
removeItem: (id) => {
set(() => {
const cart = get().cart;
if (!cart[id]) {
return { cart };
}
const newQuantity = cart[id].quantity - 1;
if (newQuantity <= 0) {
delete cart[id];
} else {
cart[id].quantity = newQuantity;
}
return { cart };
});
},
reset: () => {
set(() => {
return { cart: {} };
});
}
}));
而且效果非常好。 问题是当我尝试添加 persist
export const useCart = create<CartState>(
persist(
(set, get) => ({
cart: {},
addItem: ({ id, image, name, price }) => {
set(() => {
const cart = get().cart;
if (!cart[id]) {
cart[id] = {
id,
image,
name,
price,
quantity: 0
};
}
cart[id].quantity += 1;
return { cart };
});
},
removeItem: (id) => {
set(() => {
const cart = get().cart;
if (!cart[id]) {
return { cart };
}
const newQuantity = cart[id].quantity - 1;
if (newQuantity <= 0) {
delete cart[id];
} else {
cart[id].quantity = newQuantity;
}
return { cart };
});
},
reset: () => {
set(() => {
return { cart: {} };
});
}
}),
{
name: "cart",
getStorage: () => localStorage
}
)
);
我遇到了这个错误:
类型参数 '(set: SetState, get: GetState, api: StoreApiWithPersist<{ cart: {}; addItem: ({ id, image, name, price }: Omit
) => void;删除项目:(id:字符串) => 无效;重置:() => 无效; }>) => { ...; }' 不可分配给类型为“StoreApi | }”的参数StateCreator '.
输入 '(set: SetState, get: GetState, api: StoreApiWithPersist<{ cart: {}; addItem: ({ id, image, name, price }: Omit) => void;删除项目:(id:字符串)=>无效; 重置:() => 无效; }>) => { ...; }' 不可分配给类型 “国家创造者 ”。
我已经尝试过
export const useCart = create<StoreApiWithPersist<CartState>>
没有运气。
请问正确的方法是什么?
将 zustand 与 TypeScript 结合使用时,您应该使用 create<T>(...)
的
curried版本,如 docs 第一段中所述。
更换
export const useCart = create<CartState>(
由
export const useCart = create<CartState>()(
应该可以解决问题。
编辑:PhilJay 的答案是最好的答案。尽管这个答案被标记为最佳答案,但它已经过时了。
我也有同样的问题。我所做的是:
import create, { GetState, SetState } from 'zustand';
import { devtools, persist, StoreApiWithPersist } from 'zustand/middleware';
const useAssetStore = create<AssetStoreType, SetState<AssetStoreType>, GetState<AssetStoreType>, StoreApiWithPersist<AssetStoreType>>(
persist(
devtools((set) => ({
logo: '',
})),
{ name: 'assetStore', version: 1, getStorage: () => localStorage }
));
因此,在您的情况下,您需要明确添加:
create<CartState, SetState<CartState>, GetState<CartState>, StoreApiWithPersist<CartState>>
键入
persist
而不是键入 create
。所以在你的情况下:
export const useCart = create(
persist<CartState>(
(set, get) => ({
cart: {},
addItem: ({ id, image, name, price }) => {
set(() => {
const cart = get().cart;
if (!cart[id]) {
cart[id] = {
id,
image,
name,
price,
quantity: 0
};
}
cart[id].quantity += 1;
return { cart };
});
},
removeItem: (id) => {
set(() => {
const cart = get().cart;
if (!cart[id]) {
return { cart };
}
const newQuantity = cart[id].quantity - 1;
if (newQuantity <= 0) {
delete cart[id];
} else {
cart[id].quantity = newQuantity;
}
return { cart };
});
},
reset: () => {
set(() => {
return { cart: {} };
});
}
}),
{
name: "cart",
getStorage: () => localStorage // Note that this is not necessary, since localstorage is used by default
}
)
);
以下是文档中的示例,演示了 TypeScript 中的实现:
interface BearState {
bears: number
increase: (by: number) => void
}
const useBearStore = create<BearState>()(
devtools(
persist(
(set) => ({
bears: 0,
increase: (by) => set((state) => ({ bears: state.bears + by })),
}),
{
name: 'bear-storage',
}
)
)
)
我在项目上被旧的 TypeScript
v4
版本锁定。
当我的商店开始增长时,我开始收到奇怪的错误消息:
Argument of type ... is not assignable to type
例如
Argument of type false is not assignable to type boolean
以上开始让我烦恼。 我发现 curried 方法生成的类型并不理想。 作为解决方案,我做了以下操作:
type TPersistState = {
open: boolean;
};
type TState = TPersistState & {
toggleOpen: (open?: boolean) => void;
}
const persistState: TPersistState = {
open: false,
};
const useAppStore = create(
persist<TState, [], [], TPersistState>(
(set, get) => ({
...persistState,
toggleOpen: (open?: boolean) => {
if (typeof open === 'boolean') {
return set({ open });
}
return set({ open: !get().open });
},
}),
{
name: 'some-name',
storage: createJSONStorage(() => localStorage),
partialize: (state) =>
({
open: state.open,
}) as TPersistState,
},
),
);
以上工作没有奇怪的 TS 错误。