I've been diving deep into TypeScript recently and encountered a challenge while working with Promise.allSettled. My goal is to fetch various pieces of weather data concurrently (like hourly forecast, daily forecast, air pollution, UV index, and current weather conditions). After fetching, I'm processing these promises within a loop, specifically in a reduce function, to organize the data into a structured format.
public async fetchAllData(): Promise<FetchResult> {
try {
const results = await Promise.allSettled([
this.getHourlyForecast(23),
this.getDailyForecast(10),
this.getAirPollution(),
this.getUvIndexForecast,
this.getCurrentWeather
]);
const promiseNames:(keyof AccType)[] = [
'hourlyData',
'tenDayForecast',
'airPollution',
'uvIndex',
'currentWeather'
];
const data = promiseNames.reduce((
acc: AccType,
name: keyof AccType,
index: number) => {
if (results[index].status === 'fulfilled') {
acc[name] = (results[index]).value // error is here
} else {
acc[name] = undefined;
}
return acc;
}, {});
console.log(JSON.stringify(data.airPollution, null, 2));
return data;
} catch (error: any) {
return { error: error.message };
}
}
here is the error :
[{ "resource": "/C:/Users/Shiha/Desktop/resume/app/(weather)/class.tsx", "owner": "typescript", "code": "2339", "severity": 8, "message": "Property 'value' does not exist on type 'PromiseRejectedResult | PromiseFulfilledResult | PromiseFulfilledResult | PromiseFulfilledResult<...> | PromiseFulfilledResult<...> | PromiseFulfilledResult<...>'.\n Property 'value' does not exist on type 'PromiseRejectedResult'.", "source": "ts", "startLineNumber": 95, "startColumn": 42, "endLineNumber": 95, "endColumn": 47 }]
The crux of my issue lies in typing the results of Promise.allSettled within the reduce function. As you can see, I'm currently using (results[index] as PromiseFulfilledResult<any>).value to extract the value of fulfilled promises, but this uses any, which I'm trying to avoid to leverage TypeScript's type safety features fully.
I'm looking for 2 things:
A way to dynamically assign types to the results based on the promise it corresponds to, thus avoiding the use of
any.How to handle this within a loop, especially using the
reducefunction, in a way that TypeScript can understand and enforce the types of each result correctly.
I've met this problem so many times, but every time I just use any to skip it. I'm looking for a better way to handle this.