type OptionalArgs = | { saveInCache: (result: NonNullable) => Promise; fetchFromCache: () => Promise; } | { saveInCache?: undefined; fetchFromCache?: undefined; }; interface FetchFromMultipleSourcesResult { result: T | null; errorOccurred: boolean; } export async function fetchFromMultipleSources( fetchPromises: (() => Promise)[], args?: OptionalArgs, ): Promise> { let result = await args?.fetchFromCache?.(); if (result) { return { result, errorOccurred: false }; } if (fetchPromises.length === 0) { throw new Error("fetchPromises cannot be empty"); } let errorCount = 0; for (let i = 0; i < fetchPromises.length; i++) { const promise = fetchPromises[i]; try { result = await promise(); if (result) break; } catch (e) { console.error(e); errorCount++; } } if (args?.saveInCache && result) { await args.saveInCache(result); } result = result ?? null; return { result, errorOccurred: errorCount === fetchPromises.length, }; }