向firebase集合查询添加类型

ca1c2owp  于 2023-06-30  发布在  其他
关注(0)|答案(3)|浏览(91)

我有一个类似的函数:

async queryAll(): Promise<Product[]> {
  const response = await this.firestore.collection('products').get();
  return response.docs.map(a => a.data());
}

获取错误:
类型“DocumentData[]”不能分配给类型“Product[]”。类型“DocumentData”缺少类型“Product”中的以下属性:ID,名称
如何为这个方法添加正确的返回类型?
我在firebase/index.ts.d中可以看到什么,get函数类型看起来像什么(我使用的是npm firebase包):
get(options?: GetOptions): Promise<QuerySnapshot<T>>;
但不知道如何将其应用到我的代码中。

new9mtju

new9mtju1#

我已经找到了解决方案,需要使用withConverter,以便在从firestore集合中检索数据时添加类型
添加了工作示例,dbQuery函数中的result应具有正确的类型,例如Product[]

import firebase from 'firebase';
import { firebaseConfig } from '../firebaseConfig';

export interface Product {
  name: string;
}
 
export const productConverter = {
  toFirestore(product: Product): firebase.firestore.DocumentData {
    return { name: product.name };
  },

  fromFirestore(
    snapshot: firebase.firestore.QueryDocumentSnapshot,
    options: firebase.firestore.SnapshotOptions
  ): Product {
    const data = snapshot.data(options)!;
    return { name: data.name }
  }
};

async function dbQuery() {
  firebase.initializeApp(firebaseConfig);
  const db = firebase.firestore();
  const response = await db.collection("products").withConverter(productConverter).get();
  const result = response.docs.map(doc => {
    const data = doc.data();
    return data;
  });

  return result; // result type is Product[]
}
bq3bfh9z

bq3bfh9z2#

我发现使用TypeScript的类型Assert功能非常简单。

await db.collection('products').get() as firebase.firestore.QuerySnapshot<Product>;

对于单个文档:

await db.collection('products').doc('12345').get() as firebase.firestore.DocumentSnapshot<Product>;

对于快照:

db.collection('products')
  .onSnapshot((snapshot: firebase.firestore.QuerySnapshot<Product>) => {
    for (const doc of snapshot.docs) {
      const product = doc.data();
    }
  });

当您在文档快照上调用data()时,其类型将为Product

omjgkv6w

omjgkv6w3#

使用withConverter为集合分配泛型类型的泛型解决方案

export function assignTypes<T extends object>() {
  return {
    toFirestore(doc: T): firestore.DocumentData {
      return doc
    },
    fromFirestore(snapshot: firestore.QueryDocumentSnapshot): T {
      return snapshot.data()! as T
    },
  }
}

然后,像这样使用它:

type User = { id: string, name: string }

const users = firestore
  .collection('users')
  .withConverter(assignTypes<User>())
  .get() // Now of type firestore.QueryDocumentSnapshot<User>

相关问题