我在类型记录中有以下接口:
interface ComplexRating {
ratingAttribute1?: number;
ratingAttribute2?: number;
ratingAttribute3?: number;
ratingAttribute4?: number;
}
export interface Review {
rating: ComplexRating | number;
}为了简单起见,我想计算一下ratingAttribute1的平均评分。
因此,鉴于这些审查:
const reviews: Review[] = [
{ rating: { ratingAttribute1: 5 } },
{ rating: { ratingAttribute1: 10 } },
{ rating: { ratingAttribute2: 15 } },
{ rating: 5 }
]我可以过滤掉那些我感兴趣的评论,比如:
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
);
};现在,令人烦恼的是,类型记录不知道通过运行reviews.filter函数,我输入的Review只保护了具有rating of type ComplexType的Review的子集,还有那些具有ratingAttribute1: number;而不是ratingAttribute?: number的评论。
我想要结束的是不必重复计算中的类型检查,有效地结束如下:
const calculateAverageRating = (reviews: Review[]): number => {
const reviewsWithRating = reviews.filter(
(review) =>
typeof review.rating === 'object' &&
typeof review.rating['ratingAttribute1'] === 'number'
);
return (
reviewsWithRating.reduce(
(acc, review) => acc + review.rating['ratingAttribute1'],
0.0
) / reviewsWithRating.length
);
};但这是不可能的:

有什么方法可以达到这个级别的类型保护吗?还是有一种更整洁的方式来做这种事?
发布于 2022-05-18 16:02:31
.filter()函数将始终返回与参数相同类型的数组。这就是为什么reviewsWithRating仍然是一个Review[]的原因,即使在您过滤它之后。
要改变这一点,可以在回调中添加一个型保护:
const reviewsWithRating = reviews.filter(
(review): review is { rating: Required<ComplexRating> } =>
typeof review.rating === 'object' &&
typeof review.rating['ratingAttribute1'] === 'number'
);现在,TypeScript将知道reviewsWithRating是{ rating: Required<ComplexRating> }[]类型的。
https://stackoverflow.com/questions/72292351
复制相似问题