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

core-js and TypeScript - how do these fit together? #3956

Closed
johnnyreilly opened this Issue Jul 21, 2015 · 19 comments

Comments

Projects
None yet
7 participants
@johnnyreilly
Copy link

johnnyreilly commented Jul 21, 2015

The recent blogpost on the TypeScript 1.5 release highlighted the contrast between Babel and TypeScript in terms of ES6 compatibility.

However both are listed as Babel + core-js and TypeScript + core-js:

image

I understand that Babel ships with core-js but I'm a little confused as to what TypeScript + core-js actually means. Since TypeScript ships some of its own polyfills and core-js is entirely polyfills (as I understand) I'm puzzled as to what TypeScript + core-js actually is?

Is there a compilation flag that prevents TSC from generating super and the like so that core-js can be dropped in instead? Or is there an advised way of combining TypeScript and core-js that I haven't stumbled upon yet?

Apologies for raising it as an issue as it's more a question. I've looked on StackOverflow and found this related question:

http://stackoverflow.com/questions/31417833/using-core-js-with-typescript

However it didn't resolve my mystery. All guidance appreciated!

@RyanCavanaugh

This comment has been minimized.

Copy link
Member

RyanCavanaugh commented Jul 21, 2015

"TypeScript + core-js" is just what it sounds like - using the TypeScript compiler with the core-js polyfills.

The Kangax table is a little confusing because it's designed for measuring runtimes, not transpilers. For example, the TypeScript language isn't itself going to do anything special to support the "Array.prototype methods" row. We just add it to lib.d.ts and we're "done", but the Kangax table tests for runtime compat, which isn't going to work without a polyfill.

If we didn't include a polyfill library in our column, we'd be limited to a ~30% maximum score, which is really misleading when comparing to other downlevel transpilers that are including polyfills as part of their score. Including core-js as part of the TypeScript column just makes the top-line number apples-to-apples.

@johnnyreilly

This comment has been minimized.

Copy link
Author

johnnyreilly commented Jul 21, 2015

Thanks for that @RyanCavanaugh.

For my own part I'd come away with the impression that TypeScript was planning by 1.6 to provide near enough 100% ES6 compatibility. I took this to mean not only compilation level but also polyfills for downlevel transpilation. From what you've said I now realise it doesn't.

Is there somewhere I can look to clarify what polyfills TypeScript supplies and so which ones core-js will add into the mix? Also I'm curious to know if there's a defined policy of what TypeScript will look to polyfill and what it won't as the project progresses. Perhaps there's also guidance that I've missed on the best way to combine TypeScript with core-js as well? (Probably just as simple as including core-js with the served scripts.)

@DanielRosenwasser

This comment has been minimized.

Copy link
Member

DanielRosenwasser commented Jul 21, 2015

See the DefinitelyTyped .d.ts for core.js to get an idea of what we don't polyfill ourselves.

The rule of thumb is that if there's a canonical/sane emit that doesn't have a huge perf-hit, we'll try to support it. We don't add any runtime methods or data structures, which is more what core.js serves to do.

@kitsonk

This comment has been minimized.

Copy link
Contributor

kitsonk commented Jul 22, 2015

@aikeru I didn't realise it was a game to try to win by scoring the most points... As long as the table is clear on how what is being measured, then it is like any other table/chart.

Personally, I find it informative to see how TypeScript compares with other solutions that are looking to fill the whole gap of ES6/ES2015 in a runtime environment. TypeScript is not looking to polyfill functionality/mutate globals, only to address basic language constructs that can be fully addressed via transpilation. Others are looking to do more than that. It really depends on what you are looking for. If it is just ES6 compatibility in ES5, choosing TypeScript would likely not be a good choice.

@RyanCavanaugh

This comment has been minimized.

Copy link
Member

RyanCavanaugh commented Jul 22, 2015

To even the playing field, let's define "out of the box" as "the compiled JS runs without any other scripts loaded"

@johnnyreilly

This comment has been minimized.

Copy link
Author

johnnyreilly commented Jul 22, 2015

Thanks for the clarifications @RyanCavanaugh and @DanielRosenwasser. I don't want to participate in the bun fight this issue is fast becoming.

That said, I think it would be valuable to list somewhere in the official TypeScript documentation what ES latest => ES5/ES3 transpilation is provided by TSC "out of the box" / where "the compiled JS runs without any other scripts loaded".

Whilst it's possible to inspect the core-js typing on DT and compare that to the ES6 spec it's not a moments work. A canonical place to look would be greatly welcomed by me and a useful resource for the community I think.

How would you feel about this being added to the documentation somewhere?

@kitsonk

This comment has been minimized.

Copy link
Contributor

kitsonk commented Jul 22, 2015

@aikeru not to be rude, but I am afraid I have other things to do then read your arbitrary personal opinions in other forums. I am interested in participating in the TypeScript community, contributing to it, not randomly bashing people in a semi-neurotic way.

@RichiCoder1

This comment has been minimized.

Copy link

RichiCoder1 commented Jul 22, 2015

  • Packaging core.js, even if it's an optional component or make including it a compiler switch or something
  • Improving the transpiler so that only the needed shims are included (as a side-note, given an intelligent enough transpiler, all of these features could be provided as part of transpilation that didn't require any shim)

These two, at least, are specifically excluded in part by:
https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals#non-goals

I could agree with providing some link to Core JS. Would love some official documentation or a wiki blurb in including it in a project.

@DanielRosenwasser

This comment has been minimized.

Copy link
Member

DanielRosenwasser commented Jul 22, 2015

Would love some official documentation or a wiki blurb in including it in a project.

A wiki/handbook blurb might be useful. Perhaps we'll mention it around our non-goals, but that might not be as visible for interested users.

@RichiCoder1

This comment has been minimized.

Copy link

RichiCoder1 commented Jul 22, 2015

Would love some official documentation or a wiki blurb in including it in a project.

A wiki/handbook blurb might be useful. Perhaps we'll mention it around our non-goals, but that might not be as visible for interested users.

To use the meme, why not both? A dedicated wiki page, a mention in the getting started docs, and a [1] in non goals with a reference to aforementioned wiki page. Might require some more somewhere, but that would cover most the bases.

@mhegazy

This comment has been minimized.

Copy link
Contributor

mhegazy commented Sep 20, 2016

Starting with TS 2.0, you can use the --lib flag. you can add specific library parts as needed, e.g. --lib es2015.promise,es2016.symbol, es2016.iterables or just --lib es2015 for the whole thing.

@mhegazy mhegazy closed this Sep 20, 2016

@amcdnl

This comment has been minimized.

Copy link

amcdnl commented Sep 20, 2016

@mhegazy - does it polyfill in core-js for u automatic?

@mhegazy

This comment has been minimized.

Copy link
Contributor

mhegazy commented Sep 21, 2016

No. TypeScript does not inject any polyfills. it is up to you to chose which polyfill to use, and how to import it.
the --lib only imports the shapes of the APIs (e.g. Proxy, Promise, Map, Set, etc..) into your scope so that the compiler can check your code against them.

@johnnyreilly

This comment has been minimized.

Copy link
Author

johnnyreilly commented Sep 21, 2016

Hey @mhegazy,

I've been a happy user of target: "es2015" for some time and I'm a little confused about the overlap of functionality between target and lib. If I use lib: "es2016" do I not need target: "es2016" with TS 2? Or do I need both? Could you flesh out the overlap / differences please? I've read the docs but it's not clear to me...

@mhegazy

This comment has been minimized.

Copy link
Contributor

mhegazy commented Sep 21, 2016

No. Target is for syntactic transformations; e.g const vs a var. lib is for injecting types, e.g. Promise. Use lib if you know a specific type exits or if you have a polyfill.

@johnnyreilly

This comment has been minimized.

Copy link
Author

johnnyreilly commented Sep 21, 2016

I'm still a little confused I'm afraid. target gives you the types as well as I understand. Certainly I have Promise / Map etc to play with as long as using "target": "es2015". To quote the docs:

Getting to ES6/ES2015 built-in API declarations were only limited to target: ES6.

So there's some crossover still I'm guessing?

I feel like I've got the wrong end of the stick somehow. For my part I'm always emitting the highest possible target of ES and having Babel do the downlevel transpilation for me (it brings polyfills). I can't work out if I actually have any use for lib or not.

Is there any point in this:

tsc --target es2016 --lib es2016

Or is this fine?:

tsc --target es2016

Perhaps the question is: does lib only really come into play when target !== lib?

@kitsonk

This comment has been minimized.

Copy link
Contributor

kitsonk commented Sep 21, 2016

In ES2015, there were both syntactic and functional features.

In ES2016, there was only one syntactic feature (exponentiation) and essentially one functional (Array.prototype.includes)

In ES2017, there are a few both syntactic features (e.g. async/await) and functional features which are likely to get approved.

target describes the emit syntax that is generated by TypeScript, but it also assumes the functional features of the language will also be available at run-time. Therefore there is no need to expressly tell TypeScript that.

lib allows you to specify specifically what functional features TypeScript should "assume" when emitting. So a target of es5 but a lib that included es6 would instruct TypeScript to emit everything syntactically, but would assume that someone has loaded the functional features of ES2015.

Because ES2016 was so "small" syntactically, I think the TypeScript core team assumed it would not make sense to add a separate syntactic target and since the vast majority of run-time engines have just introduced while still implementing ES2015 features...

It is apparent that the TypeScript team are still figuring out exactly how to deliver ES2017, but considering it isn't yet ratified and syntactic features already available in TypeScript are under a compiler flag, it is likely it will take a while.

So @johnnyreilly for your use case, it is unlikely you will need to instruct TypeScript to load additional TypeScript provided libs, though if you are adapting functional patterns of future ES functionality that you then are polyfilling in some other fashion at run-time, you could use lib to load those, but you could also just include them in your compile path as well.

@johnnyreilly

This comment has been minimized.

Copy link
Author

johnnyreilly commented Sep 21, 2016

Awesome - thanks @kitsonk for a really clear explanation!

I think that, for my own use case, I'll just be using target; but if I decide to opt into some new hotness that Babel can polyfill and TypeScript support in lib then I'll be able to.

So initially I'm probably just going to be happy with tsc --target 2016 which allows me to write ES2016 code. But perhaps later I might use (for example) tsc --target 2016 --lib es2017.object.

TypeScript will let me write either. Babel will transpile either.

@johnnyreilly

This comment has been minimized.

Copy link
Author

johnnyreilly commented Sep 22, 2016

Ah - slightly misunderstood you. No matter; I think I have it now; I've written it up here if anyone wants the full details.

The tl;dr is: you need tsc --target 2015 --lib es2015,es2016,dom; there is no target es2016

@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.
You can’t perform that action at this time.