Ionic+Firebase项目遍历JSON报错:Property 'pname'不存在于类型'{}'
解决Ionic+Firebase遍历数据时的Property 'pname' does not exist on type '{}'错误
嘿,我明白你遇到的问题了!这个错误是TypeScript的类型检查在搞事情——它不知道从Firebase返回的result[i]具体是什么结构,默认把它当成了空对象{},自然就找不到pname这个属性啦。下面给你几个实用的解决办法:
方法1:定义明确的接口约束数据类型(推荐)
TypeScript最吃这一套,给你的数据结构定义一个接口,让TypeScript清楚知道每个字段的类型:
首先,在你的项目里定义一个接口(可以单独放在一个.ts文件里,或者直接在用到的文件顶部):
// 定义页面数据的接口,包含所有可能的字段 interface PageItem { pname: string; pagetitle?: string; // 可选字段用?标记 list?: Array<{ img: string; isAnimated?: boolean; }>; img?: string; name?: string; email?: string; }
然后修改你的provider.ts,给list()方法指定泛型:
export class MyProvider { masterdata : Array<PageItem>; data : Array<PageItem>; constructor(public afd: AngularFireDatabase) { } getDataByPage() { // 这里指定泛型为PageItem,让Firebase返回明确类型的Observable return this.afd.list<PageItem>('/masterdata/0/page/').valueChanges(); } }
最后在home.ts里也用这个接口约束返回结果:
export class Home { home:Array<PageItem>; data: PageItem; // 把data的类型改成PageItem constructor(public navCtrl: NavController, public navParams: NavParams, public popoverCtrl: PopoverController, public modalCtrl: ModalController,public masterdata: MyProvider ) { this.masterdata.getDataByPage().subscribe((result: PageItem[]) => { for(let i in result ) { console.log(result[i]); if(result[i].pname == "Home") { this.data = result[i]; } } }); } }
方法2:临时类型断言(快速解决)
如果你不想写接口,也可以在访问属性的时候用类型断言告诉TypeScript这个对象的结构:
this.masterdata.getDataByPage().subscribe(result => { for(let i in result ) { console.log(result[i]); // 用as断言result[i]是包含pname的对象 const item = result[i] as {pname: string}; if(item.pname == "Home") { this.data = result[i]; } } });
方法3:直接指定返回类型为any[]
虽然不推荐(会失去TypeScript的类型检查优势),但如果只是想快速绕过错误,也可以给valueChanges()指定返回类型:
// provider.ts里修改方法 getDataByPage() { return this.afd.list('/masterdata/0/page/').valueChanges() as Observable<any[]>; }
这样TypeScript就不会再纠结result[i]的类型啦,不过还是推荐第一种方法,既能解决错误,又能让代码更健壮!
内容的提问来源于stack exchange,提问作者Faisal Amdani
相关产品推荐
相关产品推荐

