TypeScript does not automatically polyfill code (check out microsoft/TypeScript#3101). The main reasoning behind this decision, as stated by @RyanCavanaugh in the corresponding GitHub issue, is:
Having the compiler determine which [ES20XX] methods to include, where to place them, and whether or not to emit polyfills, along with options for those who do not want the polyfills emitted, and ways to customize the source of these polyfills, becomes quite messy and unwarranted compared to simply incorporating a standard [ES20XX] polyfill library within your script context.
Furthermore, emitting runtime code goes against one of TypeScript's principles as highlighted in that issue:
[Non-Goal #]6. Provide additional runtime functionality or libraries. Instead, use TypeScript to describe existing libraries.
The confusion may arise from the fact that while TypeScript does downgrade certain language features when targeting earlier EcmaScript versions, the deciding factor between downleveling and polyfilling is primarily based on syntax:
If the new language feature is syntactically invalid for the targeted version, it will either be downleveled or trigger a compile-time warning. Invalid syntax cannot be polyfilled. For instance, class Foo {}
is invalid ES5 code and will consequently be transformed into a constructor function when targeting ES5.
On the other hand, if the language feature is syntactically valid for the target version, it will be emitted without any warnings. Therefore, [1,2,3].includes(0)
represents valid ES5 syntax. If an Array.prototype.includes
method is added to an ES5 engine, it will work at runtime as well. So, no polyfilling is necessary. By specifying es2017
in your lib
compiler options, you inform TypeScript about the support for ES2017 typings at runtime, hence avoiding compile-time warnings. However, adding typing libraries does not impact the runtime itself; therefore, you are responsible for polyfilling/shimming required components. The compiler cannot handle cases where the existence of methods at runtime differs from what was declared to it. This may not provide much comfort to someone encountering a runtime error, though.
Well, that's just how it goes, I suppose.
Hopefully, this explanation proves helpful. Best of luck!