interface AggregateError extends Error { name: 'AggregateError'; errors: any[]; } interface AggregateErrorConstructor { new (errors: Iterable, message?: string): AggregateError; readonly prototype: AggregateError; } /** * Like `Promise.allSettled()` but throws an error if any promises are rejected. */ export const allSettledWithThrow = async (promises: Promise[]): Promise => { const results = await Promise.allSettled(promises); const rejected = results .filter((result): result is PromiseRejectedResult => result.status === 'rejected') .map((result) => result.reason); if (rejected.length) { const message = `${rejected.length} promise(s) failed`; const globalAggregateError: AggregateErrorConstructor | undefined = (globalThis as any).AggregateError; if (globalAggregateError) { throw new globalAggregateError(rejected, message); } else { throw Object.assign(new Error(message), { name: 'AggregateError', errors: rejected, } as const) satisfies AggregateError; } } // Note: TS was complaining about using `.filter().map()` here for some reason const values: R[] = []; for (const result of results) { if (result.status === 'fulfilled') { values.push(result.value); } } return values; };