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
相关产品推荐
相关产品推荐

