Ionic 3与Angular 5应用Firebase数据获取类型不匹配错误排查
解决Type 'Observable<any[]>' is not assignable to type 'Observable
咱们先拆解一下这个错误提示:Type 'Observable<any[]>' is not assignable to type 'Observable<Menu>'. Type 'any[]' is not assignable to type 'Menu'. Property 'categories' is missing in type 'any[]'——简单说就是你代码里期望拿到一个单个Menu对象的Observable,但实际返回的是Menu数组的Observable,类型完全不匹配,所以报错了。
问题根源分析
- Firebase方法用错了:你的
Menu模型是一个包含categories属性的单个对象,但你在MenuService里用了this.db.list<Menu>('menu')——list方法是用来获取某个节点下所有子节点组成的数组的,而不是单个对象。 - 类型不匹配:在homepage.ts里,你对
snapshotChanges()的结果做了两层map,最终返回的是一个数组(每个元素是处理后的Menu对象),但你把这个结果赋值给了期望是单个Menu的this.menu变量,自然类型就冲突了。 - 模型定义有语法错误:你的
Category接口里,description: string后面少了个逗号,导致dishes: Dish[]的定义不合法,这也会影响后续的数据解析。
针对性解决方案
分两种情况,取决于你Firebase数据库的结构:
情况1:Firebase里menu节点本身就是单个Menu对象
如果你的menu节点直接包含categories属性(也就是整个menu是一个对象,不是多个子节点),那应该用object方法替代list:
修改MenuService:
@Injectable() export class MenuService { // 用object获取单个节点对象,而不是list获取数组 private menuRef = this.db.object<Menu>('menu'); constructor(private db: AngularFireDatabase) { } getMenu() { return this.menuRef; } }
修改homepage.ts的调用逻辑:
// 先确保this.menu的类型是Observable<Menu> menu: Observable<Menu>; constructor(public navCtrl: NavController, public dataService: DataServiceProvider, private menuService: MenuService) { this.menu = this.menuService.getMenu().snapshotChanges() .map(change => { // object的snapshotChanges返回单个ChangeAction,直接处理即可 return { key: change.payload.key, ...change.payload.val() } as Menu; }); }
情况2:Firebase里menu节点下是多个Menu对象
如果你的menu节点下有多个子节点,每个子节点都是一个Menu对象,那你需要调整this.menu的类型为数组:
修改homepage.ts的类型声明:
// 把类型改成Observable<Menu[]>,表示是Menu数组的Observable menu: Observable<Menu[]>;
保持MenuService和原有map逻辑不变:
你的MenuService里的list方法是对的,homepage.ts里的两层map也没问题,因为它会把每个子节点映射成Menu对象,最终组成数组,和Observable<Menu[]>类型匹配。
额外要修正的模型语法错误
你的Category接口里少了一个逗号,必须修正:
import { Dish } from "./dish.model"; export interface Category { key? : string, category: string, description: string, // 这里补上逗号 dishes: Dish[], imageName: string }
这样调整之后,类型不匹配的错误就应该解决了,同时模型解析也不会有问题。
内容的提问来源于stack exchange,提问作者Jose Adame Fernandez
相关产品推荐
相关产品推荐

