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.
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 function
s 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.