使用Firebase Firestore withConverter()时出现TypeScript错误的原因?
Firebase V9 SDK中withConverter()的TypeScript类型错误
我在使用Firebase Firestore JavaScript V9 SDK的withConverter()方法,目的是给文档数据添加TypeScript类型定义。参考了Admin SDK的实现方式,但换成前端V9 SDK后出现TypeScript错误。
我的代码
import { initializeApp } from 'firebase/app'; import { collection, getFirestore, PartialWithFieldValue, QueryDocumentSnapshot } from 'firebase/firestore'; // Firestore初始化 const firebaseConfig = { ... }; const firebaseApp = initializeApp(firebaseConfig); const firestore = getFirestore(firebaseApp); // 定义转换器 const converter = <T>() => ({ toFirestore: (data: PartialWithFieldValue<T>) => data, fromFirestore: (snap: QueryDocumentSnapshot) => snap.data() as T, }); // 这段代码正常,userColRef被正确推断为CollectionReference<User> const userColRef = collection(firestore, 'users').withConverter(converter<User>()); // 这段代码抛出TypeScript错误 const dataPoint = <T>(collectionPath: string) => { return collection(firestore, collectionPath).withConverter(converter<T>()); // <-- 错误位置 };
错误信息
No overload matches this call. Overload 1 of 2, '(converter: null): CollectionReference<DocumentData>', gave the following error. Argument of type '{ toFirestore: (data: PartialWithFieldValue<T>) => PartialWithFieldValue<T>; fromFirestore: (snap: QueryDocumentSnapshot) => T; }' is not assignable to parameter of type 'null'. Overload 2 of 2, '(converter: FirestoreDataConverter<T>): CollectionReference<T>', gave the following error. Argument of type '{ toFirestore: (data: PartialWithFieldValue<T>) => PartialWithFieldValue<T>; fromFirestore: (snap: QueryDocumentSnapshot) => T; }' is not assignable to type 'FirestoreDataConverter<T>'. The types returned by 'toFirestore(...)' are incompatible between these types. Type 'PartialWithFieldValue<T>' is not assignable to type 'DocumentData'. Type 'T extends Primitive ? T : T extends {} ? { [K in keyof T]?: FieldValue | PartialWithFieldValue<T[K]> | undefined; } : never' is not assignable to type 'DocumentData'. Type 'T | (T extends {} ? { [K in keyof T]?: FieldValue | PartialWithFieldValue<T[K]> | undefined; } : never)' is not assignable to type 'DocumentData'. Type 'Primitive & T' is not assignable to type 'DocumentData'. Type 'undefined & T' is not assignable to type 'DocumentData'.ts(2769)
解决方案
问题根源在于泛型T没有类型约束,前端V9 SDK的FirestoreDataConverter要求传入的类型必须兼容DocumentData。需要给泛型添加约束,并显式指定转换器的类型:
修改后的代码
import { initializeApp } from 'firebase/app'; // 新增导入DocumentData和FirestoreDataConverter import { collection, getFirestore, PartialWithFieldValue, QueryDocumentSnapshot, DocumentData, FirestoreDataConverter } from 'firebase/firestore'; // Firestore初始化 const firebaseConfig = { ... }; const firebaseApp = initializeApp(firebaseConfig); const firestore = getFirestore(firebaseApp); // 给泛型T添加DocumentData约束,同时显式指定返回类型为FirestoreDataConverter<T> const converter = <T extends DocumentData>(): FirestoreDataConverter<T> => ({ toFirestore: (data: PartialWithFieldValue<T>) => data, fromFirestore: (snap: QueryDocumentSnapshot) => snap.data() as T, }); // 正常使用 const userColRef = collection(firestore, 'users').withConverter(converter<User>()); // 修改dataPoint函数的泛型约束 const dataPoint = <T extends DocumentData>(collectionPath: string) => { return collection(firestore, collectionPath).withConverter(converter<T>()); };
原因说明
Admin SDK的类型系统和前端V9 SDK存在差异,前端版本对toFirestore的返回值类型检查更严格,要求必须符合DocumentData的结构。通过给泛型T添加extends DocumentData约束,确保传入的类型是Firestore支持的数据结构,同时显式指定转换器的类型为FirestoreDataConverter<T>,让TypeScript正确匹配重载,解决类型错误。
内容的提问来源于stack exchange,提问作者TinyTiger
相关产品推荐
相关产品推荐

