Need clarification of the target and lib compiler options
I find I'm confused by the target and lib options and how they interact with the features supported in the source code. I feel the docs need improving a little so am asking here before raising an issue.
I naively assumed that target specifies the version of JS that the output code requires to run (with the addition of a module loader). Thus we can always use all the advanced JS features (like object spread) that TS supports in our source and the compiler generates suitable code for the target we specify. I assume it had polyfills etc at hand and the code would just run on the target VM.
However the docs for the lib option specify the default libs depend on the target. But, libs effect what source types are available and so effect what code we can use. Thus the source features we can use depend on the target. That is not as I expected. I should say my understanding of lib is that they are typings with a different API, though the docs do not really say what they are.
I can see that here are some language features that do not depend on types and others that do. However it's not clear if that's part of the reason for this situation.
Can someone please clarify this?
A secondary question is why is there both an ES6 and an ES2015 lib when they are usual documented as being the same thing.
thanks
(This started as a comment but it got too long.)
It's a bit confusing partly because there's some history behind it. I'm not qualified to answer this authoritatively but I've been following TypeScript since early development and this is my understanding:
-
--target
tells the compiler what library version to include while compiling (for exampleES5
will give a compiler error if you usePromise
, butES6
will know all aboutPromise
) and what version of JS is emitted by the compiler (for exampleES5
will down-compile class syntax, butES6
will leave it in). -
--lib
was added later to give you better control over what library version to use while compiling without changing the emitted JS target. For example, a common problem was that you may include polyfills for ES6 library features, such asPromise
, but you want to target ES5 browsers by down-compilingclass
syntax. Before--lib
was around you either had to targetES6
to avoid compile errors aboutPromise
, then down-compile again using Babel, or you could targetES5
and provide your own type definition forPromise
so that the compiler doesn't give you an error. Now with--lib
you can simply say your--target ES5
and--lib ES6
, and the compiler will not complain aboutPromise
but still down-compile to ES5. - Neither option will cause TS to emit any library polyfills (
Promise
, etc), as you evidently found out; it's your responsibility to provide the correct runtime libraries. It only emits a few down-level language compatibility helpers, like__extends
and__awaiter
(the difference being thatclass
orasync
is not just an API that can be polyfilled at runtime, it's a language feature with syntax implications). The--lib
option is just your way of getting the right level of compile checking based on what you know you are going to have at runtime. - As for why there's both
ES6
andES2015
, that's just because ECMAScript changed the name and TS left the old name as a valid option for backwards compatibility. :)
You'll find a lot of this covered in these TS issues:
- #4168 - Normalize our lib files by compiler settings
- #6974 - Proposal: Modularize Library
TSConfig Reference links:
- target
- lib