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:
core-js/stable/promise/all-settled
promise.allsettled
ts-polyfill/lib/es2020-promise
(usescore-js
anyway)