Reputation: 43491
I have:
const neuroResponses = await Promise.allSettled(neuroRequests);
const ret = neuroResponses.filter(response => response?.value?.data?.result[0]?.generated_text?.length > 0).map(({ value }) => value.data.result[0]?.generated_text);
But I get a TypeScript issue:
Property 'value' does not exist on type 'PromiseSettledResult<AxiosResponse<any>>'.
Property 'value' does not exist on type 'PromiseRejectedResult'.
Is there a better way to type this?
Upvotes: 1
Views: 664
Reputation: 1074028
Conditional chaining doesn't change the fact that, from a type perspective, you're trying to use a property that isn't there. It just defends against your proceeding if the property contains the value undefined
. You're still trying to use a property that may not exist on the type.
You can use a type guard to filter out the failed responses. For instance, an inline type guard:
const neuroResponses = await Promise.allSettled(neuroRequests);
const ret = neuroResponses
.filter(response => "value" in response && response.value.data?.result[0]?.generated_text?.length > 0)
.map(({ value }) => value.data.result[0]?.generated_text);
If you do this a lot, you might want a type guard function:
function isSuccessful<T>(response: PromiseSettledResult<T>): response is PromiseFulfilledResult<T> {
return "value" in response;
}
Then you can use it like this:
const neuroResponses = await Promise.allSettled(neuroRequests);
const ret = neuroResponses
.filter(isSuccessful) // ***
.filter(response => response.value.data?.result[0]?.generated_text?.length > 0)
.map(({ value }) => value.data.result[0]?.generated_text);
Or
const neuroResponses = await Promise.allSettled(neuroRequests);
const ret = neuroResponses
.filter(response => isSuccessful(response) && response.value.data?.result[0]?.generated_text?.length > 0)
.map(({ value }) => value.data.result[0]?.generated_text);
Upvotes: 3