下面的语句抛出类型错误。为什么?
const x: Chat = { ...doc.data(), id: doc.id }
错误是:
类型'{id: string;}'类型'聊天'缺少以下属性:消息,名称,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
我不熟悉打字,但这看起来确实很奇怪。提前感谢
正如@TJCrowder评论的那样,您可以检查data()
方法返回的内容。它返回DocumentData
类型的对象,Typescript并不知道内容是什么。您可以尝试使用这样的类型断言,并指定对象的类型为Chat
:
const x = { ...doc.data(), id: doc.id } as Chat
但是,这可能导致键入不存在的文档(当doc.exists === false
—通常在使用DocumentReference
而不是查询时发现)。您可以断言在查询中使用的CollectionReference
的类型,而不是断言doc.data()
的类型。这对于DocumentReference
也是一样的。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 }
你可以在Typescript的文档中阅读更多关于Type Assertion
的信息。