Type 'IterableIterator<number>' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher
Asked Answered
L

3

34

I'm trying to evolve with this Slider, but I get the following error when using TypeScript React in this Next.js project:

"Type 'IterableIterator' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher."

The code is this:

import { useKeenSlider } from 'keen-slider/react'
import React, { useState } from 'react'
import 'keen-slider/keen-slider.min.css'
import './styles.css'

export default function Slider() {
  const [currentSlide, setCurrentSlide] = useState(0)
  const [loaded, setLoaded] = useState(false)
  const [sliderRef, instanceRef] = useKeenSlider({
    initial: 0,
    slideChanged(slider) {
      setCurrentSlide(slider.track.details.rel)
    },
    created() {
      setLoaded(true)
    }
  })

  return (
    <>
      <div className="navigation-wrapper">
        <div ref={sliderRef} className="keen-slider">
          <div className="keen-slider__slide number-slide1">1</div>
          <div className="keen-slider__slide number-slide2">2</div>
          <div className="keen-slider__slide number-slide3">3</div>
          <div className="keen-slider__slide number-slide4">4</div>
          <div className="keen-slider__slide number-slide5">5</div>
          <div className="keen-slider__slide number-slide6">6</div>
        </div>
      </div>
      {loaded && instanceRef.current && (
        <div className="dots">
          {[
            ...Array(instanceRef.current.track.details.slides.length).keys()
          ].map(idx => {
            return (
              <button
                key={idx}
                onClick={() => {
                  instanceRef.current?.moveToIdx(idx)
                }}
                className={'dot' + (currentSlide === idx ? ' active' : '')}
              ></button>
            )
          })}
        </div>
      )}
    </>
  )
}

I followed the Keen Slider documentation, but the example was in JavaScript. Because I'm using TypeScript, I don't know how to solve this problem.

Limbert answered 29/10, 2022 at 16:12 Comment(1)
You are transpiling into a target version of JavaScript which does not support iterating over IterableIterator. Go into your tsconfig.json and either change target to "target": "es2015" or set "downlevelIteration": trueRegale
R
55

TypeScript code is transpiled to JavaScript. TypeScript developers have to make a decision which version of JavaScript they want to target. Choosing a lower version means that the code can be executed in older browsers, ultimately reaching a larger user base. Developers can still use modern JavaScript features, as long as these features can be downleveled to older JavaScript versions.

Most modern JavaScript features can be emulated in lower versions, but we have to be explicit when dealing with IterableIterator. If you want to write code that depends on IterableIterator, you have to either increase your target version or set downlevelIteration to true.

tsconfig.json:

{
  "compilerOptions": {
    "target": "es2015"
    // or
    "downlevelIteration": true
  }
}

Further resources:

Regale answered 31/10, 2022 at 17:19 Comment(4)
I got this error when attempting to use the spread operator on a JS Map() inside a TypeScript project. I added the es2015 target (it was previously set to es5) in my tsconfig.json and it fixed the problem. ThanksCabotage
For some reason I still intermittently get this error even after setting downlevelIteration: true. Our target is es5.Aidoneus
I was getting this error despite having all targets set to either ES2015 or ES6. ES6 is supposed to be equivalent to ES2015 according to every site I read, but the error didn't go away until I changed everything to ES2015.Precis
You have to delete .next folder and then build for the changes to apply, as @cglacet pointed below.Piotr
W
15

I had the same issue, I added a target option as already suggested here:

{
  "compilerOptions": {
    "target": "ES6"
  }
}

But I also had to reset my Nextjs cache before next build worked as expected:

# next build doesn't work
rm -rf .next 
# next build works
Wrench answered 21/7, 2023 at 9:24 Comment(0)
G
0

The slide object has an attribute called abs that serves as the index, so you can change the way you map it

before:

{loaded && instanceRef.current && (
    <div className="dots">
      {[
        ...Array(instanceRef.current.track.details.slides.length).keys()
      ].map(idx => {
        return (
          <button
            key={idx}
            onClick={() => {
              instanceRef.current?.moveToIdx(idx)
            }}
            className={'dot' + (currentSlide === idx ? ' active' : '')}
          ></button>
        )
      })}
    </div>
  )}

after:

{loaded && instanceRef.current && (
    <div className="dots">
      {instanceRef.current.track.details.slides.map((slide) => {
        return (
          <button
            key={slide.abs}
            onClick={() => {
              instanceRef.current?.moveToIdx(slide.abs);
            }}
            className={
              "dot" + (currentSlide === slide.abs ? " active" : "")
            }
          ></button>
        );
      })}
    </div>
  )}
Gaygaya answered 22/11, 2023 at 15:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.