Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ES2016 target #5361

Closed
jods4 opened this issue Oct 22, 2015 · 37 comments
Closed

Add ES2016 target #5361

jods4 opened this issue Oct 22, 2015 · 37 comments
Labels
Fixed A PR has been merged for this issue Good First Issue Well scoped, documented and has the green light Help Wanted You can do this Suggestion An idea for TypeScript

Comments

@jods4
Copy link

jods4 commented Oct 22, 2015

For various reasons that are discussed in other issues, some people like to pipe TS into Babel for the downlevel (e.g. ES5) code generation. I won't reiterate here why one might want to do so.

Now that TS is starting to get ES7+ features such as async, decorators, possibly :: & co. it would be very welcome to add a ES7 (ES2016) target.

The use case today is to get raw, non transformed code from TS and process it with Babel.
The future use case is of course that JS runtimes are going to have some of those features natively supported and down-level emit won't be required anymore.

@kitsonk
Copy link
Contributor

kitsonk commented Oct 22, 2015

I still think this is challenging and that a simple "es6/es2015" or "es7/es2016" target won't solve the challenges... It almost needs some sort of granular feature flag. I am not familiar with it, but how is Babel handling these sort of control of these emits?

Also, is it a fair assumption at this point that an ES6+ feature ever be down emitted in ES6 as well as ES5/ES6? For something like exponation, the emit wouldn't change, but in theory if there was a down-emit for async to ES6, you could emit Promises but you couldn't do that to ES5.

@jods4
Copy link
Author

jods4 commented Oct 22, 2015

@kitsonk OK, I'm going on a tangent with respect to this ticket.

The business of emiting JS for down-level browsers is a complex thing, which is mostly unrelated to the TypeScript language. On several aspects, Babel does a better job than TS at this. That's why some people pipe TS (for static typing) into Babel (for ES5 emit).

Granularity is one example of this. Babel supports enabling/disabling any Transformer individually. That's why it is enough that TS passes through ES7 code, I can handle the granular transpiling with Babel.

I don't mind TS supporting more emitting options (I think granularity is #4692), but letting the ES7 code passthrough is an easy step that supports such a workflow right now.

Also, is it a fair assumption at this point that an ES6+ feature ever be down emitted in ES6 as well as ES5/ES6? For something like exponation, the emit wouldn't change, but in theory if there was a down-emit for async to ES6, you could emit Promises but you couldn't do that to ES5.

Not sure I got the point here.

@robotlovesyou
Copy link

A real world use case for this would be the next major release of Koa.js which will natively support async/await in addition to the current generator syntax. While it works nicely with async functions transpiled by Babel it does not play well with the async functions transpiled by typescript (although I guess maybe that could be addressed separately).
It also seems cleaner to me to have typescript deal with all the static analysis stuff but have a specialised tool like Babel handle the transpiling from ESn to ESm

@kitsonk
Copy link
Contributor

kitsonk commented Oct 23, 2015

Not sure I got the point here.

There are likely to be features introduce in ES7 and beyond that would be better to emit as ES6 when possible. For example you could use WeakMaps/Promises/Symbols to better polyfill functionality in ES6 which is likely more performant (and less likely to have unintended consequences). Even using let and const in the down emit can make code behave better (and be less likely to leak/interfere with other code). Let's say decorators... maybe the environment doesn't support decorators (ES7) but supports classes (ES6). Why down emit everything to ES5?

Again, I don't see anyway of properly supporting it without some sort of micro-targeting. ES7/ES2016 will be a moving target for a long time.

@robotlovesyou
Copy link

@kitsonk I may be misunderstanding you but I think Babel allows you to do exactly that. It gives you fairly granular control over what transforms and polyfills you use to emit code, so for example when targeting node >= 0.12 I can turn off the regenerator transform to take advantage of native generator support.
If there were a way to leave all es7 features untouched in the output, in exactly the same way as the es6 target leaves all es6 features untouched, then a downstream transpiler such as babel could be used to selectively transform code or not as the platform requires.

@jods4
Copy link
Author

jods4 commented Oct 23, 2015

@kitsonk exactly what @robotlovesyou said.
In babel each feature is handle by a specific transformer, and each one can be enabled/disabled as you want. So to quote your example, I could have "native" ES6 classes and transpile the decorators.

Anyway, in the long run as browsers evolve we will not transpile code anymore so a ES2016 target is required, juste like an ES6 target was added back then.

Another added benefit is that it enables TS team to add new features without downlevel support first (or ever... let in loop captures?). They did that for several features in the recent releases and I love it because it means sooner availability of async, etc. And we can still downlevel emit with Babel...

@mhegazy mhegazy added the Suggestion An idea for TypeScript label Oct 23, 2015
@mhegazy
Copy link
Contributor

mhegazy commented Oct 23, 2015

While it works nicely with async functions transpiled by Babel it does not play well with the async functions transpiled by typescript

@robotlovesyou can you elaborate on the issue here? can we file another issue with more details? if it is not working we would love to know why and what can be done to fix it.

@mhegazy
Copy link
Contributor

mhegazy commented Oct 23, 2015

We have discussed adding a --target ESNext or something along these lines. the problem is ES7/ES2016 is not finalized yet. proposals that reach stage 3 are likely to be in, but it is not clear about the other ones. for instance it is not clear that decorators will be in ES2016.

@mhegazy mhegazy added the In Discussion Not yet reached consensus label Oct 23, 2015
@jods4
Copy link
Author

jods4 commented Oct 23, 2015

@mhegazy I think TS is evolving along with ES specs.

You support ES2016 proposals so I think it makes sense to have a ES2016 target.

If a feature slips out of ES2016 -- e.g. Decorators -- I suggest you update the TS compiler to polyfill them in ES2016 and let them through in the ES2017 target.

Indeed for people that want to always be on the bleeding edge, an ESNext target that transpiles nothing at all is interesting. Especially for scenarios like Babel.

@kitsonk
Copy link
Contributor

kitsonk commented Oct 24, 2015

I may be misunderstanding you but I think Babel allows you to do exactly that.

I thought we were talking about TypeScript. The proposal was to add a new target to TypeScript. I am suggesting that @jods4 proposal over simplifies that problem and that something more is needed and that has additional considerations.

If a feature slips out of ES2016 -- e.g. Decorators -- I suggest you update the TS compiler to polyfill them in ES2016 and let them through in the ES2017 target.

The challenge with that is one day you compile and you get passed through code, and the next day you get down emitted. 😦

@jods4
Copy link
Author

jods4 commented Oct 24, 2015

I am suggesting that @jods4 proposal over simplifies that problem

I think the point is that there are different "problems" at hand, and this issue is not meant to solve your "problem".

My problem is that I want to be able to get JS code without any transpiling at all.
Your problem seems to be that you want more granularity for individual transpiling features.
They are not the same.

Today TS works with standards-based targets: ES3, ES5, ES6. Now that we start adding ES7 features we should add a matching target. It is the natural continuity of existing TS and makes perfect sense.

I don't mind introducing more flexibility, but that's a different discussion.

The challenge with that is one day you compile and you get passed through code, and the next day you get down emitted.

Is it a challenge? If you say "I want to target ES7 compliant browsers" and decorators are not in the standard anymore, then it's as it should be. Given that ES7 is not finalized yet if you ask for such a target you should be ready for that. And "down emitted" code would actually still works.

If you want stability target something stable, like ES5 or ES6.

If you want the bleeding edge, I think we need a new ESnext target or something like that, although that was not the initial point of this issue.

@kitsonk
Copy link
Contributor

kitsonk commented Oct 26, 2015

If you say "I want to target ES7 compliant browsers"

I think that is the root of the problem... We are likely to be in a constant evolving situation, where browsers will likely ever be in a static situation where you can specifically target that browser. Kangax's compatibility tables demonstrate this clearly. The agreed standards are already a moving target and then the standards that aren't even close to being finalised. There will never be something as an "ES7 compliant browser". Likely TC39 will cut ES7 as whatever is agreed at a particular point in time and everything else gets rolled forward. Like Object.observe was part of ES6, then moved to ES7 and may or may not make that, though V8 already has it implemented.

@jods4
Copy link
Author

jods4 commented Oct 26, 2015

There will never be something as an "ES7 compliant browser".

Actually, most likely there will.

It is my understanding that Edge was planned to be ES6-compliant this year and that FF and Chrome are working hard to follow suite as soon as possible.

That's great news and it means we won't need polyfills for all this stuff in 2016 (if you can target the latest browsers only, of course). Something similar will happen for ES7,you just need to wait a little longer.

Given the new TC39 yearly schedule, ES7 is ES2016 and it will be frozen next year. Give it one (or two?) years and you'll see ES2016 compliant browsers.

And then we'll need a ES2017 target next year.

@eggers
Copy link

eggers commented Nov 1, 2015

+1

I am definitely for this proposal. I already pipeline typescript and babel but would like the option of just letting typescript handle types, and do the es7 to es5 transpilation in one step.

@yortus
Copy link
Contributor

yortus commented Nov 25, 2015

+1

I was about to open the same issue and found this. At present there is no combination of compiler switches that allows ES7 async/await to just pass through - it is unconditionally down-levelled. I'd like the option to have it pass through as-is to the rest of my build pipeline.

@develar
Copy link

develar commented Jan 29, 2016

TS 1.8 breaks bluebird usage (#6631 (comment)). So, I don't want to let TS transform async/await anymore — I want to use babel (http://babeljs.io/docs/plugins/transform-async-to-module-method/). So, ES7 target (do not transform async/await) is wanted.

@johnnyreilly
Copy link

Hi @mhegazy,

Given the final feature set of ES2016 has been agreed I wonder if you might look again at an ES2016 target? In the end it's only these that made the cut:

I think you've already go the Exponentiation supported?

@mhegazy
Copy link
Contributor

mhegazy commented Feb 26, 2016

Adding the ES2016 target should be a simple task. but i wounder if it will be of any value. most comments on this thread really wanted --target ESNext

@jamiewinder
Copy link

Personally, I think the ES2016 feature set is so minimal it's barely worth the effort. TypeScript already supports the exponent operator, and includes is just a .d.ts change if you're using a polyfill library.

ESNext would be a good target to have, but what would it allow? Assuming async + await would end up there? Decorators? Bind operator?

@mhegazy
Copy link
Contributor

mhegazy commented Feb 26, 2016

ESNext would be a good target to have, but what would it allow? Assuming async + await would end up there? Decorators? Bind operator?

that is what we need to define. possibly anything that has a standards proposal even a stage 0 one.

@jods4
Copy link
Author

jods4 commented Feb 26, 2016

@jamiewinder @mhegazy I think what people who ask for --target ESnext want is basically a "passthrough". TS compiler removes what is TS-specific (i.e. type annotations, enums, etc.) and leaves everything else untouched. Main idea is to use another transpiler, more often than not, Babel.

Writing that out loud makes me wonder: maybe someone (could be community) could write a Babel plugin that removes the TS syntax?
That way one could run TS with --noEmit to verify source is correct, and then run Babel to compile it down to whatever target one wants.
Doing so would lessen the need for --target ESnext.

EDIT just realized it's not as easy as it may seem. Syntax can't be cleaned up without performing some semantic analysis. For instance you need to remove the interfaces... including in other modules where they might be imported. So it's not trivial.

@johnnyreilly
Copy link

I figured you were going to add es2016 at some point. I just wondered if now would be sensible given the state of things. Perhaps I should have raised this separately. I'm using Babel for transpilation, I thought switching to the es2016 preset would be the smoothest upgrade if TypeScript supported that target also.

@johnnyreilly
Copy link

@jods4 take a look at this: https://github.com/Microsoft/TypeScriptSamples/tree/master/es6-babel-react-flux-karma

The point is you write es2015 TypeScript and Babel transpires it down to esOld. As a workflow it rocks.

@develar
Copy link

develar commented Feb 26, 2016

Yes, TS doesn't support granular target control and so we have to use babel. @johnnyreilly To keep away from gulp and use simple workflow (use only tsconfig and npm scripts), I have written ts-babel.

@mhegazy
Copy link
Contributor

mhegazy commented Feb 26, 2016

I should note that granular transformation support is already tracked in #4692

@jods4
Copy link
Author

jods4 commented Feb 26, 2016

@johnnyreilly I do this and I'm happy 😄

But it has limitations that annoy some people. For instance, currently TS always emits ES6 code for async. You can't have TS passthrough ES2016(+) and use Babel to transpile your async code.

I personnally don't care but now that TS adheres to the current specifications of not using custom Promise implementations, some people would prefer to transpile async with Babel. And hence they would like a ES2017 / ESnext target.

@johnnyreilly
Copy link

I did not know granular targeting was on the roadmap. Awesome!

@eser
Copy link

eser commented Mar 3, 2016

+1

@tomitrescak
Copy link

Is there any way for async/await not to be transpiled already today?

@bootstraponline
Copy link
Contributor

Is there any way for async/await not to be transpiled already today?

no

@DanielRosenwasser
Copy link
Member

Because the original issue is for an ES2016 target, I'm going to say an ESNext target should be discussed separately.

@DanielRosenwasser DanielRosenwasser added Help Wanted You can do this and removed In Discussion Not yet reached consensus labels Jun 7, 2016
@DanielRosenwasser DanielRosenwasser added this to the TypeScript 2.1 milestone Jun 7, 2016
@DanielRosenwasser DanielRosenwasser added the Good First Issue Well scoped, documented and has the green light label Jun 7, 2016
@nucleartide
Copy link

👍 , TypeScript is basically unusable in my current Ember.js stack (which uses Babel) if I can't turn off async/await transpilation.

@toddwong
Copy link

+1 for a target of "esnext" (or maybe just "edge"), which just remove the typescript specific things (types/enums/namespaces/etc..)

@alex-kinokon
Copy link

For those of you who use Babel, I have written a Babel plugin native-async-for-typescript, which reverts the TypeScript async/await transpilation back to your original async function.

@panuhorsmalahti
Copy link

panuhorsmalahti commented Sep 7, 2016

Another reason for adding ES7/ES8 transpile "support" in TypeScript is that it could enable es2016.d.ts and es2017.d.ts automatically.

What's the best practice on including these definitions files at the moment?

EDIT: Solved this by updating to TypeScript 2.x and adding the following to compilerOptions in tsconfig.json:
"lib": ["es2017", "dom"]

@mhegazy mhegazy modified the milestones: Community, TypeScript 2.1 Sep 29, 2016
@mhegazy mhegazy added the Fixed A PR has been merged for this issue label Oct 15, 2016
@mhegazy
Copy link
Contributor

mhegazy commented Oct 15, 2016

The original request should be handled by #11407. --target ES2016 and --target ES2017 should be supported now.

@mhegazy mhegazy modified the milestones: TypeScript 2.1, Community Oct 15, 2016
@mhegazy mhegazy closed this as completed Oct 15, 2016
@mhegazy
Copy link
Contributor

mhegazy commented Nov 10, 2016

7b9a42f adds a new --target esnext as well to get experimental features passed through.

@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Fixed A PR has been merged for this issue Good First Issue Well scoped, documented and has the green light Help Wanted You can do this Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests