I can't define the correct type for the following function which returns value from mongodb:
export const getPopulatedCountriesByCountryIdsDB = async (countryIds: any[]) => {
try {
const query = {
id: {$in: countryIds}
}
const db = await getDb();
const collectionName = process.env.MONGO_DB_COLLECTION_POPULATED_COUNTRY!;
const countries = await db?.collection(collectionName).find<Country>(query).toArray();
return countries;
} catch (err) {
logger.error('Error in getPopulatedCountriesByCountryIdsDB:', err);
}
}
interface Country
defined as following:
export interface Country {
id: ObjectId;
cities: []
};
I invoke it as following:
const countries = await getPopulatedCountriesByCountryIdsDB(countriesIds!);
But later, when I try to access some nested properties as following:
const country = countries!.filter((country: any) => country.id === countryId);
const cities = country.cities.filter((city: any) => city.id === cityId);
I get the following error:
Property 'cities' does not exist on type 'Country[]'
How can I properly define the type Country
? Thank you!
UPDATE: After remarks from caTS I have updated my code as following:
Country Type:
export interface Country {
id: ObjectId;
cities: any[]
};
But get the following error:
Property 'cities' does not exist on type 'Country[]'
UPDATE 1: If I use it without passing the type to this function here:
const countries = await db?.collection(collectionName).find(query).toArray();
I get the following error:
Property 'cities' does not exist on type 'WithId[]'.
CodePudding user response:
Property 'cities' does not exist on type 'Country[]'
This error arises because you are filtering an array down to one element, and then trying to read a property from that array. Instead you need to take an element from the array and then read the property from the element.
const country = countries!.filter((country: any) => country.id === countryId);
// at this point country is a list containing one element
// read out the first value
const selectedCountry = country[0]
const cities = selectedCountry.cities.filter((city: any) => city.id === cityId);
You will want some error handling in case the array is empty - i.e. if the countryId does not match any country.id.
You will also need to do the same process when working with the selected city.