lomine
lomine

Reputation: 1181

React typescript - Type must have a '[Symbol.iterator]()' method that returns an iterator

I have a demo here

https://stackblitz.com/edit/react-ts-shopping-cart-ssofgc?file=Shop.tsx

Sorry this isn't the best question but

My demo is a simple shopping cart using React and Typescript.

Products can be added and removed from a cart.

My demo in stackblitz works but I have an error using the same code in my app.

In my app I get an error in the removeFromCart

I get the error here

const removeFromCart = (
    e: React.MouseEvent<HTMLInputElement, MouseEvent>,
    item: IProduct
  ) => {
    let cartCopy = [...cart]; // Error here - Type 'IProduct' must have a '[Symbol.iterator]()' method that returns an iterator.
    cartCopy = cartCopy.filter(cartItem => cartItem.id !== item.id);
    setCart(cartCopy);
  }; 

The error is

Type 'IProduct' must have a '[Symbol.iterator]()' method that returns an iterator.

Can anyone explain this error or how to fix it.

Upvotes: 2

Views: 6492

Answers (2)

kamranicus
kamranicus

Reputation: 4417

It is likely due to lib option in tsconfig.json. I had updated to some newer packages (Redux 7, React 16+) and noticed my config was woefully out-of-date.

Before:

tsconfig.json

"target": "es2015",
"lib": [ "dom", "es5", "es2015.symbol", "es2015.core", "es2015.promise" ]

This config was throwing the error when using React.useState.

After:

tsconfig.json

"target": "es2015",
"lib": [ "dom", "es2015" ]

Specifically, adding es2015.iterable will be enough for this specific error but there was no reason in my case not to add es2015.

Upvotes: 1

andersryanc
andersryanc

Reputation: 969

It's weird you get the error where you say you are, seeing as you aren't using item on that line... I would think that your cart type would need to be "array like", ie. include [Symbol.iterator]() as part of it. You can read more about Symbol.iterator on MDN.

EDIT: I see now (in your stackblitz link) that cart comes from const [cart, setCart] = useState([]);, so it's definitely an array, so that shouldn't be an issue. Seems to me like there is something up with either your editor or your local project configuration...

Maybe you could try and be more explicit about your variable types. For instance, items and cart both appear to be IProduct[], so you could change them be written like:

  const [cart, setCart] = useState<IProduct[]>([]);

  const items: IProduct[] = [
    {
      id: 1,
      name: "Product One",
      price: 12
    },
    {
      id: 2,
      name: "Product Two",
      price: 45
    },
    {
      id: 3,
      name: "Product Three",
      price: 23
    }
  ];

Upvotes: 1

Related Questions