You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular+Firebase教程中CdkDragDrop与编译类型错误求助

Angular-Firebase教程中CdkDragDrop与Firestore类型不匹配问题解决

初始CdkDragDrop类型错误

在实现拖拽功能时,模板中drop($event)触发类型错误:

Argument of type 'CdkDragDrop<Task[] | null, any, any>' is not assignable to parameter of type 'CdkDragDrop<Task[], Task[], any>'.ngtsc(2345)
app.component.ts(20, 7): Error occurs in the template of component AppComponent.

对应的初始drop方法代码:

drop(event: CdkDragDrop<Task[]>): void {
  if (event.previousContainer === event.container) {
    return;
  }
  const item = event.previousContainer.data[event.previousIndex];
  this.store.firestore.runTransaction(() => {
    const promise = Promise.all([
      this.store.collection(event.previousContainer.id).doc(item.id).delete(),
      this.store.collection(event.container.id).add(item),
    ]);
    return promise;
  });
  transferArrayItem(
    event.previousContainer.data,
    event.container.data,
    event.previousIndex,
    event.currentIndex
  );
}

修改后出现Firestore编译错误

调整drop方法类型为CdkDragDrop<Task[] | null>后,项目内无报错,但编译时出现Firestore类型不匹配错误:

修改后的drop方法代码:

drop(event: CdkDragDrop<Task[] | null>): void {
  if (event.previousContainer === event.container) {
    return;
  }
  const item = event.previousContainer?.data?.[event.previousIndex];
  if (!item) {
    return;
  }
  this.store.firestore.runTransaction(() => {
    const promise = Promise.all([
      this.store.collection(event.previousContainer!.id).doc(item.id).delete(),
      this.store.collection(event.container!.id).add(item),
    ]);
    return promise;
  });
  transferArrayItem(
    event.previousContainer!.data!,
    event.container!.data!,
    event.previousIndex,
    event.currentIndex
  );
}

编译终端报错信息:

Error: node_modules/@angular/fire/compat/firestore/interfaces.d.ts:13:18 - error TS2430: Interface 'DocumentSnapshotExists<T>' incorrectly extends interface 'DocumentSnapshot<DocumentData>'.
  The types returned by 'data(...)' are incompatible between these types.
    Type 'T' is not assignable to type 'DocumentData | undefined'.
      Type 'T' is not assignable to type 'DocumentData'.

13 export interface DocumentSnapshotExists<T> extends firebase.firestore.DocumentSnapshot {
                    ~~~~~~~~~~~~~~~~~~~~~~

  node_modules/@angular/fire/compat/firestore/interfaces.d.ts:13:41
    13 export interface DocumentSnapshotExists<T> extends firebase.firestore.DocumentSnapshot {
                                               ~
    This type parameter might need an `extends firebase.firestore.DocumentData` constraint.
  node_modules/@angular/fire/compat/firestore/interfaces.d.ts:13:41
    13 export interface DocumentSnapshotExists<T> extends firebase.firestore.DocumentSnapshot {
                                               ~
    This type parameter might need an `extends firebase.firestore.DocumentData | undefined` constraint.


Error: node_modules/@angular/fire/compat/firestore/interfaces.d.ts:23:18 - error TS2430: Interface 'QueryDocumentSnapshot<T>' incorrectly extends interface 'QueryDocumentSnapshot<DocumentData>'.
  The types returned by 'data(...)' are incompatible between these types.
    Type 'T' is not assignable to type 'DocumentData'.

23 export interface QueryDocumentSnapshot<T> extends firebase.firestore.QueryDocumentSnapshot {
                    ~~~~~~~~~~~~~~~~~~~~~

  node_modules/@angular/fire/compat/firestore/interfaces.d.ts:23:40
    23 export interface QueryDocumentSnapshot<T> extends firebase.firestore.QueryDocumentSnapshot {
                                              ~
    This type parameter might need an `extends firebase.firestore.DocumentData` constraint.


Error: node_modules/@angular/fire/compat/firestore/interfaces.d.ts:26:18 - error TS2430: Interface 'QuerySnapshot<T>' incorrectly extends interface 'QuerySnapshot<DocumentData>'.
  Types of property 'docs' are incompatible.
    Type 'QueryDocumentSnapshot<T>[]' is not assignable to type 'QueryDocumentSnapshot<DocumentData>[]'.
      Type 'QueryDocumentSnapshot<T>' is not assignable to type 'QueryDocumentSnapshot<DocumentData>'.
        The types returned by 'data(...)' are incompatible between these types.
          Type 'T' is not assignable to type 'DocumentData'.

26 export interface QuerySnapshot<T> extends firebase.firestore.QuerySnapshot {
                    ~~~~~~~~~~~~~

  node_modules/@angular/fire/compat/firestore/interfaces.d.ts:26:32
    26 export interface QuerySnapshot<T> extends firebase.firestore.QuerySnapshot {
                                      ~
    This type parameter might need an `extends firebase.firestore.DocumentData` constraint.


Error: node_modules/@angular/fire/compat/firestore/interfaces.d.ts:29:18 - error TS2430: Interface 'DocumentChange<T>' incorrectly extends interface 'DocumentChange<DocumentData>'.
  The types returned by 'doc.data(...)' are incompatible between these types.
    Type 'T' is not assignable to type 'DocumentData'.

29 export interface DocumentChange<T> extends firebase.firestore.DocumentChange {
                    ~~~~~~~~~~~~~~

  node_modules/@angular/fire/compat/firestore/interfaces.d.ts:29:33
    29 export interface DocumentChange<T> extends firebase.firestore.DocumentChange {
                                       ~
    This type parameter might need an `extends firebase.firestore.DocumentData` constraint.


Error: node_modules/rxfire/firestore/lite/interfaces.d.ts:8:29 - error TS2314: Generic type 'AggregateQuerySnapshot<T>' requires 1 type argument(s).

 8 export type CountSnapshot = lite.AggregateQuerySnapshot<{
                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 9     count: lite.AggregateField<number>;
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 }, any, DocumentData>;
   ~~~~~~~~~~~~~~~~~~~~~



** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **


× Failed to compile.

解决方案

1. 让Task类型继承DocumentData

Firestore要求自定义数据类型必须扩展DocumentData,修改你的Task接口:

import { DocumentData } from '@angular/fire/firestore';

export interface Task extends DocumentData {
  id?: string;
  title: string;
  // 其他你定义的Task属性
}

2. 优化drop方法的类型处理

避免使用过多非空断言(!),增加安全检查:

drop(event: CdkDragDrop<Task[] | null>): void {
  if (event.previousContainer === event.container) {
    return;
  }

  const previousData = event.previousContainer.data;
  const currentData = event.container.data;
  if (!previousData || !currentData) return;

  const item = previousData[event.previousIndex];
  if (!item) return;

  this.store.firestore.runTransaction(async () => {
    await Promise.all([
      this.store.collection(event.previousContainer.id).doc(item.id).delete(),
      this.store.collection(event.container.id).add(item),
    ]);
  });

  transferArrayItem(previousData, currentData, event.previousIndex, event.currentIndex);
}

3. 确保Angular Fire与Firebase版本兼容

编译错误中的rxfire和@angular/fire类型问题,通常是版本不匹配导致的。更新到兼容版本:

npm install @angular/fire@latest firebase@latest
  • Angular 15+建议使用@angular/fire ^7.5.0+ 和 firebase ^9.22.0+

4. 临时跳过库类型检查(可选)

如果上述方法仍未解决,可以在tsconfig.json中添加配置跳过库类型检查,但这是临时方案,优先解决版本和类型继承问题:

{
  "compilerOptions": {
    "skipLibCheck": true
  }
}

内容的提问来源于stack exchange,提问作者3474

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 14:44:56