如何在应用程序模型中使用 FieldValue.serverTimestamp

Thi*_*man 4 firebase typescript google-cloud-firestore

在我的 Typescript 应用程序代码中,我定义了一个模型,该模型使用 Firestore 在服务器上生成的时间戳。当文档从数据库返回时,该字段将是一个 ISO 字符串。我想在我的应用程序中使用相同的模型定义来写入和读取数据,但这会带来一个问题。

我通常会写这样的东西:

interface Document {
  title: string,
  createdAt: string
}

async function addDocument(document: Document): Promise<string> {
  const id = await firestore.collection('documents').add(someDocument)
  return id
}

async function getDocumentData(documentId: string): Promise<Document> {
  const doc = await firestore.collection('documents').doc(documentId).get()

  invariant(doc.exists, `No document available with id ${documentId}`)
  return doc.data() as Document
}

const someDocument: Document = {
  title: "How to",
  createdAt: firestore.FieldValue.serverTimestamp()
}

const newDocumentId = await addDocument(someDocument)
Run Code Online (Sandbox Code Playgroud)

现在,Typescript 编译器抱怨 的值someDocument不兼容,因为createdAt它被定义为字符串。

之前,我通过欺骗编译器相信它是一个带有createdAt: firestore.FieldValue.serverTimestamp() as string.

随着最近对 Typescript 的更新,这种容忍度似乎随着我使用的严格设置而消失了。编译器现在告诉我:

类型“FieldValue”无法转换为类型“string”。

我不想再次围绕编译器工作,而是想知道处理这个问题的正确方法是什么?

- 编辑 -

由于 Firestore 时间戳行为即将发生变化,我再次查看此内容,发现 API 实际上并未返回 ISO 字符串,而是返回 Date 对象。因为 Date 对象具有自动字符串转换功能,所以我的代码始终有效,但从这个意义上说,类型定义是不正确的。但这对我最初的问题并没有太大改变。

Thi*_*man 8

Firebase 的新行为是Timestamp从 db 方法返回对象,而不是 Date 对象。

在我的类型定义文件中,我现在导入 Timestamp 类型(为此需要 Typescript 2.9),然后在我的模型中使用它,如下所示:

export type FirestoreTimestamp = import("firebase").firestore.Timestamp;

export interface LockableItem {
  isLocked: boolean;
  lockedBy?: UserId;
  lockedAt?: FirestoreTimestamp;
}
Run Code Online (Sandbox Code Playgroud)

当使用 FieldValue 设置 lockAt 字段时,您现在可以简单地执行以下操作:

const item: LockableItem = { 
  isLocked: true,
  lockedAt: FieldValue.serverTimestamp() as FirestoreTimestamp, 
  lockedBy: "someuser" 
}
Run Code Online (Sandbox Code Playgroud)