我在打字稿中有以下介面:
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
);
};
現在,令人討厭的是,Typescript 不知道通過運行reviews.filter我鍵入的函式,我只保護了評論的一個子集,這些評論有rating of type ComplexType,還有那些有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
);
};
但這不是開箱即用的:

有沒有辦法實作這種級別的型別保護?或者有沒有一種更簡潔的方法來做這種事情?
uj5u.com熱心網友回復:
該.filter()函式將始終回傳與作為引數給出的相同型別的陣列。這就是為什么reviewsWithRating仍然是 a 的原因Review[],即使在您過濾它之后也是如此。
要更改這一點,您可以在回呼中添加型別保護:
const reviewsWithRating = reviews.filter(
(review): review is { rating: Required<ComplexRating> } =>
typeof review.rating === 'object' &&
typeof review.rating['ratingAttribute1'] === 'number'
);
現在 TypeScript 會知道那reviewsWithRating是 type { rating: Required<ComplexRating> }[]。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/477478.html
