调用TypeScript类成员函数编译通过却报TypeError错误原因咨询
问题原因与解决方案
核心原因
你给statistics标注的TypeScript类型RatingStatisctics只是编译阶段的类型校验提示,运行时modifiedOffer.rating_statistics根本不是RatingStatisticsImpl类的实例。
比如这个数据如果是从后端接口、localStorage读取,或者通过JSON.parse生成的,它本质就是个普通JavaScript对象——没有关联RatingStatisticsImpl的原型链,自然找不到addRatingStatistic方法,所以控制台会报“不是函数”的错误。
为什么外部函数能正常运行?
外部函数不依赖对象的原型链,它直接接收参数处理逻辑,不需要调用者是某个类的实例,所以不管你传入的是普通对象还是类实例,只要参数符合要求就能运行。
解决办法
1. 将普通对象转换为类实例
给RatingStatisticsImpl添加构造函数或静态转换方法,把普通对象转成类实例,这样就能调用类内的方法:
class RatingStatisticsImpl implements RatingStatisctics { // 声明接口对应的属性 avgRating: number; totalCount: number; // 接收初始数据的构造函数 constructor(data: Partial<RatingStatisctics>) { Object.assign(this, data); } addRatingStatistic(rating: number, isPositive: boolean) { // 你的方法实现逻辑 this.totalCount++; this.avgRating = (this.avgRating * (this.totalCount - 1) + rating) / this.totalCount; } } // 使用时转换为类实例 const statistics = new RatingStatisticsImpl(modifiedOffer.rating_statistics); statistics.addRatingStatistic(newRating.rating, true);
也可以用静态方法简化转换:
class RatingStatisticsImpl implements RatingStatisctics { static fromPlainObject(data: RatingStatisctics): RatingStatisticsImpl { return new RatingStatisticsImpl(data); } // 构造函数和方法实现同上 } // 使用 const statistics = RatingStatisticsImpl.fromPlainObject(modifiedOffer.rating_statistics);
2. 保留外部函数/改用纯函数
如果你的逻辑不需要维护类实例的状态,或者状态可以通过参数传递,继续用外部纯函数是更简单的选择,比如:
function addRatingStatistic(statistics: RatingStatisctics, rating: number, isPositive: boolean) { // 直接修改传入的对象或者返回新对象 statistics.totalCount++; statistics.avgRating = (statistics.avgRating * (statistics.totalCount - 1) + rating) / statistics.totalCount; } // 调用 addRatingStatistic(modifiedOffer.rating_statistics, newRating.rating, true);
内容的提问来源于stack exchange,提问作者Wadkan
相关产品推荐
相关产品推荐

