I'd like to pass a data i.e. id
, title
to a cart page as array of objects, but Typescript screaming at me that I did sth wrong, but i don't know what.
error(1):
Argument of type '(state: CartState) => { carts: (string | SugarProductSchema)[]; }' is not assignable to parameter of type 'CartState | Partial | ((state: CartState) => CartState | Partial)'. Translation: I was expecting CartState | Partial | ((state: CartState) => CartState | Partial), but you passed (state: CartState) => { carts: (string | SugarProductSchema)[]; }
// zustand state management store
import create from 'zustand';
import { devtools, persist } from 'zustand/middleware';
import { SugarProductSchema } from '@/types/sugar-product-schema';
interface CartState {
carts: SugarProductSchema[];
addToCart: (id: string, title: string) => void;
}
const useCartStore = create<CartState>()(
devtools(
persist(
(set) => ({
carts: [],
addToCart: (id, title) =>
set((state) => ({ carts: [...state.carts, id, title] })), // here is the error(1)
}),
{
name: 'cart-storage',
}
)
)
);
export default useCartStore;
product card component:
// (...)
const addToCart = useCartStore((state) => state.addToCart);
const handleCartProducts = () => {
addToCart(id, title);
toast.success('Dodano produkt do koszyka');
console.log(id);
};
// (...)
Right now, it shows that error(1) which is mentioned above, but it still saves the data: e.g. id
and title
but in the way I don't want to: It's generating one array and adding values to this array instead of creating objects with id
and title
e.g.
it should like this:
[
//product 1 {id:"t512521512", title:"random title"}
//product 2 {id:"xxxxxx", title:"randosasasam title"}
//and so on
]
SugarProductSchema type file
export type SugarProductSchema = {
title: string;
brand: string;
price: number;
coverImage: string;
id: string;
slug: string;
};
CodePudding user response:
So I would guess the issue is that
set((state) => ({ carts: [...state.carts, id, title] }))
Isn't quite what you were wanting. You'll end up with something like
{ carts: [ cart1, cart2, cart3, id, title] }
Whereas that set
function wants an array of SugarProductSchema
and you're giving it (string | SugarProductSchema)[]
. It's the rogue strings of id
and title
that are throwing it off.
Maybe what you're looking for is
set((state) => ({ carts: [ ...state.carts, { id, title } ] })
But then you're missing several fields from SugarProductSchema
and it will be angry about that too. The main idea here is that the carts
field in your CartState
needs to be an array of SugarProductSchema
types and nothing else.
If you just want the id
and title
to be required you might consider making the other fields in SugarProductSchema
optional. Like
export type SugarProductSchema = {
title: string;
brand?: string;
price?: number;
coverImage?: string;
id: string;
slug?: string;
};
If they need to be required then you'll need to add those fields in when using set