Home > Blockchain >  Typescript target & library configuration to use Promise.allSettled on older browsers
Typescript target & library configuration to use Promise.allSettled on older browsers

Time:03-23

I am using typescript version 4.3.5 and node version 14.18.1. I am compiling my code targeting old as well as new browsers (target=es5 in tsconfig). I am using Promise.all as well as Promise.allSettled both in my source code.

On older browsers, specifically Safari on IPhone 8, IOS version 11, I am getting client side errors with Promise.allSettled.

As per my understanding, when using target=es5, typescript should compile to make the code compatible with older devices hence Promise.allSettled should work. Please help me understand the issue! Following is my tsconfig.json

{
  "compilerOptions": {
    "sourceMap": true,
    "target": "es5",
    "module": "commonjs",
    "esModuleInterop": true,
    "outDir": "dist",
    "jsx": "react",
    "lib": [
      "ES2020.Promise",
      "dom",
      "webworker"
    ],
    "skipLibCheck": true
  },
  "include": [
    "typings/node.d.ts",
    "typings/modules.d.ts",
    "**/*.ts",
    "**/*.tsx"
  ],
  "exclude": [
    "node_modules",
    "**/*.scss.d.ts"
  ]
}

CodePudding user response:

As in the question Why do I need a polyfill with Typescript?, TypeScript doesn't automatically provide backwards-compatibility implementations ("polyfills"). Consequently, the target tsconfig does less than you think it would: It only rewrites syntax like arrow functions and generators, not libraries like Promise. In fact, the only reason you can resolve Promise.allSettled in the first place is that you've specifically listed "ES2020.Promise" in your lib list, which tells TypeScript that in your environment you can assume you have access to ES2020 Promises (specifically Promise.allSettled).

From those lib docs, emphasis mine:

You may want to change these [lib entries] for a few reasons:

  • Your program doesn’t run in a browser, so you don’t want the "dom" type definitions
  • Your runtime platform provides certain JavaScript API objects (maybe through polyfills), but doesn’t yet support the full syntax of a given ECMAScript version
  • You have polyfills or native implementations for some, but not all, of a higher level ECMAScript version

As in the question Promise.allSettled in babel ES6 implementation, you have several options to provide a polyfill yourself, but a notable one is es.promise.all-settled.js in core-js. You can integrate those into your Webpack build using the polyfills entry point pointing to a short polyfill-import-only JS file, though the suggestion to use babel-polyfill has been deprecated in favor of core-js/stable.

You would need to import or require one of these:

  • Related