jaredpalmer / tsdx

Zero-config CLI for TypeScript package development
https://tsdx.io
MIT License
11.28k stars 507 forks source link

Spread transpilation issue with `Array` -- downlevelIteration usage? #659

Closed ndrbrt closed 4 years ago

ndrbrt commented 4 years ago

Current Behavior

Suppose we have this code:

const A: Array<number> = [
    ...[...Array(10)].map(() => 0),
    ...[...Array(5)].map(() => 1)
]

const B: Array<number> = []
for (let i = 0; i < 10; i++) {
    B.push(0)
}
for (let i = 0; i < 5; i++) {
    B.push(1)
}

console.log('A:', A)
console.log('B:', B)

If I run the code within a test with yarn test (i.e. tsdx test), everything is fine and the output is:

A: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 ]
B: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 ]

If I build the library and import it in node, though, I get something different:

A: [ <15 empty items> ]
B: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 ]

Expected behavior

I'd expect the built library imported in node to behave as it does in the tests:

A: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 ]
B: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 ]

Additional context

Your environment

Software Version(s)
TSDX 0.13.0
TypeScript 3.8.3
Browser -
npm/Yarn Yarn
Node v10.15.0
Operating System macOS 10.14.6
agilgur5 commented 4 years ago

I'll have to look into it later, but it sounds like this might be related to TypeScript's downlevelIteration, for which there's this issue: https://github.com/jaredpalmer/tsdx/issues/376 . That should behave the same between tsc and tsdx though 🤔

ndrbrt commented 4 years ago

Yes thank you, I did see #376, even though actually I solved my own issue by just using "option B".

I opened this one though, because, as you pointed out, I find it strange the inconsistency between tsc and tsdx

agilgur5 commented 4 years ago

I think it might be that the tsconfig target matters to TS for this transform; per the docs, it sounds like it only does something when targeting ES5 or below.

TSDX ignores your setting and forces target to ESNext and transpiles the rest down with @babel/preset-env, so that's probably the difference unless you're not using target?

Per https://github.com/jaredpalmer/tsdx/issues/376#issuecomment-566750042, it sounds like adding @babel/preset-env with loose: false to your babelrc should make it transpile down

Also if you're transpiling to Node (and not browser), there's a relevant TSDX flag mentioned in that issue too -- tsdx build --target node