How to use promise.allSettled with typescript?

42
November 21, 2020, at 9:40 PM

Typescript build is failing as it does not seem to like Promise.allSetttled even though I have set ts config comilerOptions with "lib": [ "ES2020.Promise" ],

It seems as though the response for promise.allSettled does not include result or reason.

When running typescript build I get the following error:

Property 'reason' does not exist on type 'PromiseSettledResult<IMyPromiseResult>'.

and

Property 'value' does not exist on type 'PromiseRejectedResult'.

My code block looks like this and as you can see, I am trying to access reason and result from eaech of the promises that get resolved.

const myPromise = async () : Promise<IMyPromiseResult> {
  return new Promise((resolve) => {
    resolve("hello world")
  })
}
const data = await Promise.allSettled([
  myPromise()
]);
const response = data.find(res => res.status === 'fulfilled')?.result;
if(!response) {
  const error = data.find(res => res.status === 'rejected')?.reason;
  throw new Error(error);
}

How can I update the Promise.allSettled declaration to include the correct interfaces?

Answer 1

Define the find callback as type guard, that returns a type predicate:

type IMyPromiseResult = string
const response = data.find(
  (res): res is PromiseFulfilledResult<string> => res.status === 'fulfilled'
)?.value;
if (!response) {
  const error = data.find(
    (res): res is PromiseRejectedResult => res.status === 'rejected'
  )?.reason;
  throw new Error(error);
}

Demo Playground

Answer 2

Like Bergi mentioned TypeScript does not know if the type is PromiseFulfilledResult / PromiseRejectedResult when checking types.

The only way is to cast the promise result. This can be done because you already verified that the resolved promise is either fulfilled or rejected.

See this example:

const myPromise = async (): Promise<string> => {
  return new Promise((resolve) => {
    resolve("hello world");
  });
};
const data = await Promise.allSettled([myPromise()]);
const response = (data.find(
  (res) => res.status === "fulfilled"
) as PromiseFulfilledResult<string> | undefined)?.value;
if (!response) {
  const error = (data.find(
    (res) => res.status === "rejected"
  ) as PromiseRejectedResult | undefined)?.reason;
  throw new Error(error);
}
READ ALSO
Is there any way to pass a React component to Push notification using service worker and node js?

Is there any way to pass a React component to Push notification using service worker and node js?

I am looking for a solution where I can pass a react component (let's take a modal component) to the push notification parameter using service worker and node jsMy service worker code for normal push notification code is-

42
In PDFMake I set the height and weight of table, but it isn&#39;t work

In PDFMake I set the height and weight of table, but it isn't work

I've created tables with pdfmakeThe pagesize and the columns size was fixed

30
Get Firebase token from external API in my test cases

Get Firebase token from external API in my test cases

I have written custom nodejs authentication utilising the firebase token based auth module

43
env variables set from the code are not available in imported modules in node.js

env variables set from the code are not available in imported modules in node.js

How to set environment variables in the code so they are available in imported NPM modules?

49