Using latest JavaScript features in TypeScript, such as ES2018
Asked Answered
O

1

25

I have tried searching through TypeScripts documentation on their configurtion and can't seem to find the answer to what should be a simple question.

Simply, how does one configure the typescript compiler so that it knows what JavaScript feature sets we are using?

So for example, ES2019 lands and i think 'Ohh want to get me some of that'. In that situation what do i need to upgrade, to allow the compiler to transpile and pollyfill what it needs to?

The lib option in the tsconfig confuses me and the docs don't explain much about the available libraries. I can't find anything on them directly either.

So lets say ES2019 comes out and i add the lib option for it (Assuming there will be one). Does that mean i can now use ES2019 features? If i wish to support everything from ES2019 down do i need to add the libs for every other version below it? Or does adding the ES2019 lib provide all i need?

Where do those libraries come from? Are they part of the core TypeScript libarary and so to get more i have to upgrade, or can i simply upgrade a seperate package and it will all work?

Finally do those lib provide every needed to fully support that version of the spec. Or is it a subset of features?

In our project we currently use TypeScript Version 2.5.3

I realize thats a whole lot of questions so any information on anything, or links to documentation, would be greatly appreciated.

Odisodium answered 26/6, 2018 at 12:52 Comment(1)
You may find this answer useful #50986994Statolatry
S
63

The story is a bit more complex, and we should begin by separating it in two: language features and runtime features.

ES Language Features

When we say language features we mean changes to the core JavaScript language syntax. For example ES 2015 adds support for classes, arrow functions (=>), and for-of iteration

Typescript tries to implement all stable language features proposals as soon as possible and will down-compile them to the ES version specified as the target option to the compiler. So this means if you have the latest Typescript compiler, which adds support for a fresh new ES 2019 language feature, you will be able to down-compile it all the way down to ES3. Typescript will emit the code necessary to make such features work in whatever version of ES you are targeting.

And you can see this in action now. If you target ES5, arrow functions are compiled into regular functions and use a _this local variable to captures this. Classes are compiled to a function and the apropriate fields on the prototype set.

ES Runtime Features

In addition to the language features, we have certain runtime features that describe what built-in object types are available, and what methods and fields those runtime objects have. Examples of new object types in recent versions of ES would be Promise or Proxy.

Typescript does not provide poly-fills for such features, if the runtime does not offer support for these you will need to come with your own poly-fill implementation if you want to use them.

Typescript does however need to know what built-in objects exist at runtime and what their methods/fields are, this is where the lib option comes in. It allows you to specify what the runtime environment will look like.

So you could for example target es5, but specify that the runtime will have all the build-in objects in conformance with the es2015 standard (some might be implemented by the runtime itself, others may be added by you through poly-fills)

The intersection of the two

The division above is a simplification, in that some language features rely on the existence of certain built-in objects and methods.

For example, the async/await language feature relies on the existence of promises. So if you use async/await and target es5 you will get an error that the Promise constructor does not exist. If you target es5 but you specify lib: [ 'es2015', 'dom' ] you will no longer get an error as you have told the compiler that even though you wish to down compile to es5, at runtime the Promise constructor will exist as per the es2015 runtime specification represented in that particular lib(not the compiler's problem how this will happen, poly-fills or built-in runtime behavior).

Generally if such a reliance exists, the typescript compiler will issue an error that certain types are missing and you can upgrade your lib, or change your target (which will change the default libs used), but you will have to ensure that the runtime has the necessary support.

The exceptions

It might not always be possible to down-compile language features all the way down to es3 (either because of missing runtime features, or just because of the high cost of implementing the feature does not make it a priority for the compiler team). An example would be property accessors (get/set) when targeting es3, which is unsupported. The compiler should warn you however if you are using an unsupported language feature/ target combination.

Statolatry answered 26/6, 2018 at 13:35 Comment(7)
That explains it all brilliantly thanks. I didn't realize the language features were core to the version of the TypeScript. Nor did i realize that the run time features were not auto polly filled by TypeScript either. I'm running an angular app and its providing the pollyfills for us. i didn't realize this. Next investigation is what exactly it is thats being pollyfilled. Thanks!Odisodium
more info github.com/Microsoft/TypeScript/issues/…Prey
Thanks for explaining, however, there is this article mariusschulz.com/blog/… that says: "Luckily, TypeScript 2.1 now supports compiling asynchronous functions to ES3 and ES5." The article goes on to show how Typescript compiles async/await down to ES3. Does this contradict anything in your answer?Cropdusting
@YehudaMakarov Not sure how that contradicts anything in my answer. You can downcompile the async/await language features to es3 that is not an issue, you will still need to come with your own polifill of Promise if your runtime does not include it. Everything I say in the section The intersection of the two still applies and applies to es3 just as much, I was just using es5 as an example.Statolatry
I guess I thought that in the post I mentioned, it seemed like there was a poly fill for a promise that was generated. I don’t know if that is right or wrong. I think I understand from you that for whatever was in that post, there must be a poly fill generated for promise end of story.Cropdusting
@YehudaMakarov There is some code generated for the async/await syntax, but the generated code still requires a preexisting implementation of Promise either in the runtime or polyfilled. The article says this explicitly: "Note that, in order to have your code run successfully in ES3 or ES5 environments, you need to provide a Promise polyfill since promises were only introduced in ES2015."Statolatry
@TitianCernicova-Dragomir thank you so much, i glossed over that. very clear now. (I saw a few of your answers on this topic.) Power to you :)Cropdusting

© 2022 - 2024 — McMap. All rights reserved.