In my TypeScript code, I have defined the following interfaces:
interface ComplexRating {
ratingAttribute1?: number;
ratingAttribute2?: number;
ratingAttribute3?: number;
ratingAttribute4?: number;
}
export interface Review {
rating: ComplexRating | number;
}
My goal is to calculate an average rating for the ratingAttribute1
attribute. For example, given these reviews:
const reviews: Review[] = [
{ rating: { ratingAttribute1: 5 } },
{ rating: { ratingAttribute1: 10 } },
{ rating: { ratingAttribute2: 15 } },
{ rating: 5 }
]
I want to filter the reviews to focus only on the ones with ratingAttribute1
. This is the function I have created for calculating the average rating:
const calculateAverageRating = (reviews: Review[]): number => {
const reviewsWithRating = reviews.filter(
(review) =>
typeof review.rating === 'object' &&
typeof review.rating['ratingAttribute1'] === 'number'
);
return (
reviewsWithRating.reduce((acc, review) => {
let newValue = acc;
if (typeof review.rating === 'object') {
const rating = review.rating['ratingAttribute1'];
if (rating) {
newValue += rating;
}
}
return newValue;
}, 0.0) / reviewsWithRating.length
);
};
However, TypeScript does not recognize the type guarding done by the reviews.filter
function, which can be seen in this screenshot:
Is there a way to improve this type guarding and eliminate the need for repeating type checks in the calculation function?