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?