首页 > 解决方案 > 为什么此语句会引发打字稿错误?

问题描述

以下语句引发类型错误。为什么?

const x: Chat = { ...doc.data(), id: doc.id }

错误是:

键入'{ id:字符串;}' 缺少“聊天”类型的以下属性:消息、名称、createdAt ts(2739)

扩展操作数提供对象的三个元素,id 由第二个操作数提供。

我正在使用 Vue 3.0.0、firebase 9.0.2 和 typescript 4.1.5

这是整个组件:

import { ref } from 'vue'
import { projectFirestore, Timestamp } from '@/firebase/config'
// import Chat from '@/types/Chat'

interface Chat {
  id?: string
  message: string
  name: string | null
  createdAt: Timestamp
}

import {
  collection as collect,
  query,
  orderBy,
  onSnapshot,
} from 'firebase/firestore'

const getCollection = (collection: string) => {
  const documents = ref<Chat[]>()
  const error = ref<string>()
  try {
    const q = query(
      collect(projectFirestore, collection),
      orderBy('createdAt', 'desc')
    )
    const unsubscripe = onSnapshot(q, (querySnapshot) => {
      const results: Chat[] = []
      querySnapshot.forEach((doc) => {
        const x: Chat = { ...doc.data(), id: doc.id }
        doc.data().createdAT && results.push(x)
      })
      documents.value = results
    })
  } catch (err) {
    if (err instanceof Error) {
      error.value = err.message
    } else {
      throw Error('Unknown Error')
    }
  }
  return { documents, error }
}

export default getCollection

我是打字稿的新手,但这看起来确实很奇怪。提前致谢

标签: typescriptfirebasevue.jsgoogle-cloud-firestore

解决方案


正如@TJCrowder评论的那样,您可以检查该data()方法返回的内容。它返回类型的对象,DocumentDataTypescript 并不真正知道内容是什么。您可以尝试使用这样的类型断言并指定对象的类型为Chat

const x = { ...doc.data(), id: doc.id } as Chat

但是,这可能会导致错误输入不存在的文档(doc.exists === false通常在使用 aDocumentReference而不是查询时发现)。doc.data()您可以断言CollectionReference您在查询中使用的类型,而不是用 断言该行的类型。这对 aDocumentReference也一样。Typescript 将确保您已正确处理文档首先不存在的情况。

collect(projectFirestore, collection) as CollectionReference<Chat>
// ...

// x will be a Chat object when `doc.exists === true` (which it is in queries)
const x = { ...doc.data(), id: doc.id }

您可以Type Assertion在 Typescript 的文档中了解更多信息。


推荐阅读