firebase - ¿Por qué esta declaración lanza un error de TypeScript?
La siguiente declaración lanza un error de tipo. ¿Por qué?
const x: Chat = { ...doc.data(), id: doc.id }
El error es:
El tipo '{ id: string; }' no tiene las siguientes propiedades del tipo 'Chat': message, name, createdAt ts(2739)
El operador de propagación proporciona tres elementos del objeto, y el id es proporcionado por el segundo operador.
Estoy usando Vue 3.0.0, Firebase 9.0.2 y TypeScript 4.1.5
aquí está todo el componente:
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
Soy nuevo en TypeScript, pero esto parece extraño. Gracias de antemano
Respuesta #1
Como comentó @TJCrowder, puedes verificar qué devuelve el método data(). Devuelve un objeto de tipo DocumentData y Typescript realmente no sabe cuáles son los contenidos. Puedes intentar usar una aserción de tipo así y especificar que el objeto será de tipo Chat:
const x = { ...doc.data(), id: doc.id } as Chat
Sin embargo, esto puede llevar a escribir incorrectamente documentos que no existen (cuando doc.exists === false - generalmente se encuentra al trabajar con un DocumentReference en lugar de consultas). En lugar de afirmar el tipo en la línea con doc.data(), puedes afirmar el tipo del CollectionReference que usaste en la consulta. Esto funciona igual para un DocumentReference también. Typescript se asegurará de que hayas manejado correctamente el caso en que un documento no exista primero.
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 }
Puedes leer más sobre Aserción de Tipo en la documentación de Typescript.
