添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
失落的炒饭  ·  CAP_SYS_ADMIN之重写device ...·  1 年前    · 
欢乐的骆驼  ·  C# 程序中使用 SQLite ...·  2 年前    · 
痴情的火龙果  ·  Python | ...·  2 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I've been trying to use Promise.allSettled on NodeJS with Typescript recently, and I'm facing issues with the response. the allSettled method returns an array with status: "rejected" | "fulfilled" and a value, in case it's fulfilled. The problem is, when I try to access the value of the response, I get the following errors:

Property 'value' does not exist on type 'PromiseSettledResult<unknown>'.
Property 'value' does not exist on type 'PromiseRejectedResult'.ts(2339)

Below I'll leave a simple example so you can copy the code and try yourself:

const p1 = Promise.resolve(50); 
const p2 = Promise.resolve(100); 
const promiseArray = [p1, p2]; 
Promise.allSettled( promiseArray ). 
  then( results => results.forEach( result =>  
    console.log(result.status, result.value)));

If I run this code on my project, I get an error because of result.value at the end.

I'm running my node on version 12.18.3 on Windows, and I've set my target on the tsconfig.json as ES2020 to be able to use the method itself.

You only have a value attribute where the status is fulfilled, and you're not checking for that. – jonrsharpe Sep 7, 2020 at 20:21 @jonrsharpe OMG I can't believe I've spent 3 hours breaking my brain and now you tell me it is this simple. It's solved now, I can't believe it. Thank you so much! – Cassio Groh Sep 7, 2020 at 20:27 Still, the TS error seems wrong - PromiseRejectedResult should not have value but PromiseSettledResult should? – Michael Liquori Jan 15, 2021 at 4:25

Got same error in case of filter promises array:

const promises = ids.map((id) => <some BE API call>);
const resolvedPromises = await Promise.allSettled(promises);
resolvedPromises.filter(({ status }) => status === 'fulfilled').map((p) => p.value);

Error screenshot

The problem is allSettled returns PromiseSettledResult, which is not exported at all (I use lib.es2020.promise in tsconfig):

interface PromiseFulfilledResult<T> {
    status: "fulfilled";
    value: T;
interface PromiseRejectedResult {
    status: "rejected";
    reason: any;
type PromiseSettledResult<T> = PromiseFulfilledResult<T> | PromiseRejectedResult;

and .map doesn't understand that all rejected promises were filtered in filtered method.

So, I even can't import types and cast values to them.

As a temporary solution I suppressed ESLint and TSC rules with comments:

  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore

Then I created same to PromiseFulfilledResult interface in the project and used types casting:

resolvedPromises.filter(({ status }) => status === 'fulfilled').map((p) => (p as PromiseFulfilledResult).value);

As a result I got rid of on error and ESLint/TS rules ignoring comments.

@jonrsharpe answered it: You only have a value attribute where the status is fulfilled, and you're not checking for that.

So using my own example, it can be fixed as the following:

const p1 = Promise.resolve(50); 
const p2 = Promise.resolve(100); 
const promiseArray = [p1, p2]; 
Promise.allSettled( promiseArray ). 
  then( results => results.forEach( result =>  
    console.log(result.status,
                result.status === 'fulfilled' && result.value

It now verifies if the promise was fulfilled and then prints the value, if it's the case.

This would be a better answer if you show how to apply that information to produce working code. – jonrsharpe Sep 7, 2020 at 20:30 @jonrsharpe Alright. I'm sorry, it's my very fisrt question here and I started learning coding 3 months from now only. I appreciate your time! – Cassio Groh Sep 7, 2020 at 20:37

You can avoid this error if you make a type statement after calling the allSettled method. For example, you can immediately enter a type for typescript as follows:

const promises = await Promise.allSettled([
  fetch(url).then((response) => response.json()),
  fetch(url).then((response) => response.json()),
]) as {status: 'fulfilled' | 'rejected', value: SomeType}[];

After that it will work correctly:

const resolvedPromises = promises.filter(({ status }) => status === 'fulfilled');
const responses = resolvedPromises.map((promise) => promise.value);

You could just type cast the result of Promise.allSettled, for instance:

const [
      someData,
      otherData
    ] = (await Promise.allSettled([
      this.someRepository.count(),
      this.otherRepository.count(),
    ])) as PromiseFulfilledResult<number>[];
 // will verify the promises, but ts doesn't get it
 this.verify(someData, otherData)
 console.log(otherData.value) // ts is okay

Number is the type returned from the promise, if you want to type promises with different typings, you could also use [PromiseFulfilledResult<number>, PromiseFulfilledResult<string>]

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.