In my code, I have a function called range
that produces ranges. The implementation is as follows:
export const range = (min: number, max: number) => {
// ...
return {
// ...
*[Symbol.iterator]() {
let n = min
while (n <= max) yield n++
}
}
}
Array.from(range(1, 5))
gives [1, 2, 3, 4, 5]
, as you'd expect. However, [...range(1, 5)]
gives [{[Symbol.iterator]: ƒ}]
(array of length 1, containing the range object), which is clearly not correct. If I attach range
to the window
object and call it from the browser console, [...range(1, 5)]
gives [1, 2, 3, 4, 5]
, as expected.
Upon further debugging, it seems the spread operator is being transpiled to this:
// console.log(() => [...range(1, 5)])
ƒ () { return [].concat(range(1, 5)) }
This would work OK if what was being spread was an array, but fails for other types of iterables.
.tsconfig
is identical to ones I've used before, targeting ESNext
, and changing downlevelIteration
to either true
or false
does nothing, so I'm fairly confident the problem isn't there.
It looks like this is something to do with Babel, but I can't work out how to configure it correctly. Legacy browser support isn't much of a concern - if it's working on latest Chromium and Firefox, I'm happy.
package.json
:
"browserslist": "last 3 chrome versions, last 3 firefox versions"
.babelrc
:
{ "presets": [ [ "preact-cli/babel", { "modules": "commonjs" } ] ] }
preact.config.js
is identical to the one here: preact.config.js
permalink. Here's the relevant part:
webpack(config, env, helpers, options) {
// ...
config.module.rules = config.module.rules.map(rule => {
if (rule.loader === 'babel-loader') {
const use = [
{
loader: 'babel-loader',
options: rule.options
},
{
loader: 'ts-loader'
}
]
return {
...rule,
loader: undefined,
options: undefined,
use,
}
}
// ...
})
// ...
}
How would I go about fixing this?
Finally fixed this by simply removing
babel-loader
altogether. I replaced the relevant part ofpreact.config.js
with this:I'd still be curious to see answers for how to fix this without removing Babel entirely, though.