microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.89k stars 12.47k forks source link

Transpiling ES6 generators into a ES5 state machine? #3975

Closed d180cf closed 8 years ago

d180cf commented 9 years ago

This must have been discussed here, but I couldn't find that discussion. So what's the reason for not supporting es6 generators when targeting es5?

In my spare time I'm writing a tsumego (it's like a mating problem in chess) solver in js which is supposed to be run on a tsumego hosting site like goproblems. This means that the solver must be es5-compatible. The solver itself is a fairly complicated variation of the depth-first search which is, obviously, recursive and can easily go 30-40 stack frames deep. Debugging such a recursive algorithm is a nightmare. I obviously needed a way to implement a special tsumego debugger that would let me use F10, F11, Shift+F11 to suspend and resume the solver at some interesting locations in the search tree, but a conventional recursive function doesn't allow to do that: it either runs to the end or just hangs due to some bug causing a tricky infinite loop 30-or-so levels deep in the search tree. So I had to rewrite the solver in a non recusrive form, which made it much less elegant. Today I've realized that what I actually needed is a recursive generator that would yield at every node in the search tree and yield* itself when it needs to go deeper.

I'm aware of transpilers like traceur that can do this transformation, but I'm afraid that this won't work with tsc well: if I write yiled* in a ts file, vs2015 will complain about the syntax, tsc will simply fail and traceur won't be able to do much due to ts-specific type annotations.

basarat commented 9 years ago

I'm aware of transpilers like traceur that can do this transformation, but I'm afraid that this won't work with tsc well: if I write yiled* in a ts file, vs2015 will complain about the syntax, tsc will simply fail and traceur won't be able to do much due to ts-specific type annotations.

You can compile with --target es6 to strip out annotations and then pass it through to traceur / others.

So what's the reason for not supporting es6 generators when targeting es5

Just work that needs to be done. It will come with release 1.6 :https://github.com/Microsoft/TypeScript/issues/1664

d180cf commented 9 years ago

Will I lose the ability to debug the original .ts files via source maps? Theoretically a tool like traceur could take into account a preexisting source map and generate a composition of source maps, but I have a doubt that traceur is this advanced.

Just work that needs to be done. It will come with release 1.6

Thanks. This answers my question.

DanielRosenwasser commented 9 years ago

To be clear, targeting ES6 with async will be supported in 1.6. Not downlevel support.

My understanding is that the work required is understood (#1781), but the team is still weighing the complexity/gain tradeoff.

danquirk commented 9 years ago

As mentioned, this is on the table, we just haven't done/committed to it yet.

oliverjanik commented 8 years ago

Will this be implemented? why is this issue closed?

mhegazy commented 8 years ago

Please note, this is gated on https://github.com/Microsoft/TypeScript/issues/5595

kuudihxquuwhxq commented 8 years ago

Any progress on this? #5595 has been resolved.

RyanCavanaugh commented 8 years ago

Downlevel generator support has been declined due to excessive complexity and inability to achieve 100% feature parity. Notes at #10307

kuudihxquuwhxq commented 8 years ago

For anyone looking for a solution, here is how I solved it.

I set target: "es6" in tsconfig compilerOptions. This is all I do for dev, it works fine for me in chrome 52, but I needed to set module: "commonjs" as well because chrome complained about import statements. Then for production I just pass the output through babel.

For example I'm using webpack so my webpack.config.js looks like this:

const typescript_loader = process.env.NODE_ENV === 'production' ?
  'babel-loader?presets[]=es2015!ts-loader' :
  'ts-loader';

// lines omitted

  module: {
    loaders: [
      // other loaders
      { test: /\.tsx?$/, loader: typescript_loader },
    ],
    preloaders: { ... },
  }

// rest omitted
jonaskello commented 8 years ago

This was sad news for the part of react/redux community that have adopted redux-saga for side-effect where generator functions are essential.

@nhjk I think regenerator is a more lightweight work-around.

kdalgaard commented 8 years ago

Very sad, indeed...

@jonaskello Do you have an example of how you use regenerator with Webpack to support redux-saga?

jonaskello commented 8 years ago

@kdalgaard Sorry, I have no examples for webpack close. However I know this starter is using regenerator with jspm. Maybe you can have a look and do the same for webpack.

tomitrescak commented 7 years ago

If async await landed in TS 2.1, and these are using generators, how come that generators are not possible to include? Thanks!

mhegazy commented 7 years ago

Generator support should be available in the next release. see https://github.com/Microsoft/TypeScript/issues/1564.