Property 'reason' does not exist on type 'PromiseSettledResult<never>'. Even though I have filtered the settled results so that only rejection remain

Viewed 74

I want to extract all rejected promises. However, even though I filter out the promises that have been rejected, my typescript interpreter still shows that the promises could still be fulfilled. It occurs in the code below

const promises = .... // generate a bunch of promises
const results = await Promise.allSettled(promises)

const errors = results.filter(result => result.status === 'rejected')

// Errors out here -> 'Property 'reason' does not exist on type 'PromiseSettledResult<never>''
const reasons = errors.map(error => error.reason)

Why does it show this Property 'reason' does not exist on type 'PromiseSettledResult<never>'. error even though I have filtered the list to make sure it only contains rejected promise? How can I fix this?

1 Answers

Problem

The type for Array.filter looks like this:

filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];

– TypeScript/lib/lib.es5.d.ts#L1367

You'll be able to see the return type is S which is an extension of T where T is the type of value. In your situation, the value is results which has a type of PromiseSettledResult<void>[] hence the error you have.

Solution

TypeScript by itself isn't able to understand that result.status === 'rejected' filters the array to only be rejected promises. You can use a type predicate to help TypeScript narrow your type:

const errors = results.filter(
  (result): result is PromiseRejectedResult =>
    result.status === 'rejected'
)

TypeScript Playground

Related