What is the reason for requiring an ES7/array polyfill even if the tsconfig target is established as ES5?

My tsconfig.json file contains the following settings, including adding "es2017" for using Array.includes:

{
  "compilerOptions": {
    "lib": [
      "es6",
      "es2017",
      "dom"
    ],
    "module": "es6",
    "target": "es5"
  }
}

However, I realized that I need to include import 'core-js/es7/array'; in my polyfills.ts to ensure compatibility with Internet Explorer 11 for using Array.includes. Since the target in my tsconfig.json is set to es5, which lacks support for Array.includes.

What is the reason behind needing to add this polyfill?

Answer №1

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!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating a Typescript interface for a anonymous function being passed into a React component

I have been exploring the use of Typescript in conjunction with React functional components, particularly when utilizing a Bootstrap modal component. I encountered some confusion regarding how to properly define the Typescript interface for the component w ...

platform designed for handling various fields of identical types

I am dealing with multiple transactions that I intentionally do not want to group into an array. Instead, I prefer to separate them as individual fields. For example: { ['fixtureId']: { transactionId: string; donation: boolea ...

What steps are involved in building a modal pop-up in Angular without using any pre-existing libraries

I am looking to create a modal popup when a button is clicked. I want to achieve this without relying on any additional dependencies. The method I have used below successfully creates a fully functional modal, but I am unsure if this is the best way to do ...

Ways to obtain the scrollWidth and offSetWidth of a div that is being utilized as an ngx-datatable-cell-template within an ngx-datatable

How can I retrieve the scrollWidth and offSetWidth of a div that is included in a child component being loaded as an ngx-datatable-cell-template inside ngx-datatable? I am consistently receiving values of 0. I have added a template variable for the div el ...

Can someone assist me in configuring the mobile display for an Angular website?

I'm currently working on a website and I'm in need of some assistance to fix the mobile view. The main issue I'm facing is with the menu which contains 5 buttons. While I'm happy with how it looks on a laptop or desktop, the mobile view ...

What is the process for comparing two objects in TypeScript?

There is a unique class named tax. export class tax { private _id: string; private _name: string; private _percentage: number; constructor(id: string = "", taxName: string = "", percentage: number = 0) { thi ...

What is the best way to implement typing in getServerSideProps using Next.js with TypeScript?

I'm currently working on a project using NextJs and TypeScript, but I've encountered an issue with types in the getServerSideProps function. In my code snippet for getServerSideProps, I am retrieving data using context.query. However, despite my ...

Can a unique intrinsic type be created from scratch?

Ever since template literals were introduced in Typescript (PR), we've had access to various useful functions in our types: Uppercase Lowercase Capitalize Uncapitalize For more information, refer to the official documentation. Although it may seem ...

Asyncronous calls in Angular involve executing tasks without

The issue seems to be related to the timing of updates for the controlSelected and isAssessmentDataLoading variables. The updateQuestions() method is invoked within the ngOnInit() method, which is triggered when the component is initialized. However, the ...

Enhancing Angular Material: requiring more user engagement for rendering to occur

Encountering an unusual issue with Angular Material: certain components require an additional event, like a click or mouse movement on the targeted div, to trigger the actual rendering process. For instance, when loading new rows in mat-table, some empty ...

Implementing express-openid-connect in a TypeScript project

Trying to incorporate the express-openid-connect library for authentication backend setup with a "simple configuration," an issue arises when attempting to access the oidc object from express.Request: app.get("/", (req: express.Request, res: express.Respon ...

Definition file for mapbox-gl-draw in Typescript, also known as d.ts file

I attempted to define the mapbox-gl-draw project in a typed manner but unfortunately, I was unsuccessful. Can anyone provide some guidance on this? Here is how the javascript file looks: 'use strict'; var Setup = require('./src/setup&apos ...

Encountering difficulty when determining the total cost in the shopping cart

I am currently working on a basic shopping cart application and I am facing an issue when users add multiple quantities of the same product. The total is not being calculated correctly. Here is my current logic: Data structure for Products, product = { ...

Stripe-node does not return metadata when accessing a Checkout Session's line items

I have successfully set up a stripe checkout session where I am passing the products from the request's body in the line_items property. Each product in the product_data includes metadata with the product's id. try { const cart: ICart[] = ...

Discovering the type in Typescript without explicitly defining a type variable for the callback

I am looking for a solution to wrap rxjs subscribe's next callback with my own function: type Handler<T> = (value: T) => void; export function withTryCatch<T>(callback?: Handler<T>): Handler<T> { return (value: T) => ...

What are the steps to avoid TypeScript from automatically installing and referencing its own @types in the AppDataLocal directory?

I'm encountering a perplexing issue where it appears that TypeScript is setting up its own version of React in its unique global cache system (not entirely sure what to call it? presuming that's the case) and utilizing it within my project. In p ...

How to Retrieve the Access Token from Instagram using Angular 2/4/5 API

I have integrated Instagram authentication into my Angular 2 project using the following steps: Begin by registering an Instagram Client and adding a sandbox user (as a prerequisite) Within signup.html, include the following code snippet: <button t ...

The promise chain from the ngbModal.open function is being bypassed

I'm currently working on implementing data editing within a component. My task involves checking if any of the data fields have been altered, and if so, prompting a confirmation pop-up to appear. If the user confirms the change, the data will then be ...

The enigma of TypeScript

Whenever I try to declare or initialize data members in a class, the following methods never seem to work: var view: string[]; var view: string[] = []; let view: string[]; let view: string[] = []; Even though the TypeScript documentation states that it s ...

FIXED-IONIC 3: The 'questions' property is missing from the 'Object' type

Encountering an issue with a single line of code and exhausted all resources in attempts to resolve it. Seeking assistance for my simple quiz, disregarding the current data presentation. The trouble arises within my data.ts file, specifically at one parti ...