在我的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)
现在,Typescript编译器抱怨someDocument
的值不兼容,因为createdAt
被定义为字符串。
之前,我通过诱使编译器相信它是createdAt: firestore.FieldValue.serverTimestamp() as string
的字符串来攻击这个。
随着最近对Typescript的更新,这个容差似乎已经消失,我正在使用严格的设置。编译器现在告诉我:
类型'FieldValue'无法转换为'string'类型。
我不知道再次解决编译器问题,我想知道处理这个问题的正确方法是什么?
- 编辑 -
由于Firestore时间戳行为的即将发生的变化,我再次看到这一点,我发现API实际上并没有返回ISO字符串而是返回Date对象。因为Date对象具有自动字符串转换,所以我的代码始终有效,但在这种意义上类型定义不正确。这不会改变我最初的问题。
答案 0 :(得分:1)
Firebase的新行为是从db方法返回Timestamp
对象,而不是Date对象。
在我的类型定义文件中,我现在导入Timestamp类型(你需要使用Typescript 2.9),然后在我的模型中使用它:
export type FirestoreTimestamp = import("firebase").firestore.Timestamp;
export interface LockableItem {
isLocked: boolean;
lockedBy?: UserId;
lockedAt?: FirestoreTimestamp;
}
使用FieldValue设置lockedAt字段时,您现在可以执行以下操作:
const item: LockableItem = {
isLocked: true,
lockedAt: FieldValue.serverTimestamp() as FirestoreTimestamp,
lockedBy: "someuser"
}