在强制转换Typescript类上调用方法

时间:2018-12-02 12:22:49

标签: angular typescript firebase google-cloud-firestore

我正在使用Cloud Firestore投射到运行良好的对象。但是似乎我无法在该对象上调用方法。这是我的模型定义-

contact.ts

export class Contact {
  id: string
  firstname: string
  lastname: string
  email: string

  getFullname() {
    return this.firstname + this.lastname
  }
}

contact.service.ts

@Injectable()
export class ContactService {
  getAll(raiseId: string): Observable<Contact[]> {
    this.contactsCollection = this.afs.collection<IContact>('contacts')
    this.contacts$ = this.contactsCollection.snapshotChanges().pipe(
      map(actions => actions.map(a => {
        const contact = a.payload.doc.data() as Contact;
        const id = a.payload.doc.id;
        return { id, ...contact };
      }))
    );
    return this.contacts$;
  }
}

contact.component.ts

@Component({
  selector: 'contact-view',
  templateUrl: './contact-view.component.html',
  styleUrls: ['./contact-view.component.scss']
})
export class ContactViewComponent implements OnInit {
  contacts$: Observable<Contact[]>;
  contacts: Contact[];

  constructor(
    public contactService: ContactService
  ) { }

  ngOnInit() {
      this.contacts$ = this.contactService.getAll();
      this.contacts$.subscribe(contacts => {
        this.contacts = contacts;
      })
    })
  }
}

component.component.html

<div *ngFor="let contact in contacts">{{contact.getFullname()}}</div>

但是getFullname()方法只会引发错误

  

TypeError:_v.context。$ implicit.getFullname不是函数

有人可以解释为什么如果有一种方法可以在强制转换对象上调用函数吗?

1 个答案:

答案 0 :(得分:3)

您不能简单地将Firestore返回的对象强制转换为任何对象并假设它可以正常工作。您通过调用data()获得的对象只是一个普通的JavaScript对象,其属性与文档的字段相匹配。就这样。它没有任何方法,并且将该对象强制转换为其他对象不会为您创建任何方法。强制转换只是改变TypeScript关于该对象是什么的概念,在这种情况下,您欺骗了TypeScript认为您确实拥有Contact实例,而实际上却没有。

如果要将Firestore数据对象转换为Contact对象,则必须将数据对象的属性复制到新的Contact对象中。一种简单的方法是使用Object.assign()