Búsqueda de sitios web

firebase - Conformidad de la interfaz de Typescript con consultas de Firestore


¿Cómo trabajo con Firebase y mis propias interfaces de Typescript?

Es decir, tengo una función aquí que va a necesitar el objeto completo Payment, (no solo el delta), así que lo obtengo a través del objeto DocumentReference.

function doSomethingWithPayment(payment: Payment) {
   console.log(payment.amount); 
}


exports.resolveStripeCharge = functions.firestore.document('/payments/{paymentId}')
    .onWrite((change : Change <DocumentSnapshot>) => {

        change.after.ref.get().then((doc: DocumentSnapshot )=> {
            const payment : Payment =   doc.data(); // tslint warning here. 
            doSomethingWithPayment(payment); 

        })


[ts]
Type 'DocumentData' is not assignable to type 'Payment'.
  Property 'amount' is missing in type 'DocumentData'.
const payment: Payment

Entiendo que el objeto devuelto no necesariamente cumplirá con la interfaz, pero en cualquier caso, ¿qué debería hacer aquí si quiero imponer la tipificación?

¿Simplemente uso:

 const payment : Payment =   <Payment>doc.data();

¿O hay una solución mucho mejor?

Respuesta #1

Dado que doc.data() siempre devuelve un DocumentData, que es simplemente {[field: string]: any}, no creo que haya una mejor manera de convertir eso en un Payment que mediante un casting. Podrías escribir:

const data = doc.data();
const payment = {amount: doc.amount, /*and so on for the remaining members*/};

sin un casteo, pero no creo que eso sea mejor en términos prácticos. Para mí tendría más sentido que DocumentData fuera simplemente any (como el retorno de JSON.parse para dar un ejemplo); podrías abrir un problema en el proyecto para proponer eso.

Respuesta #2

No estoy seguro de si esto ayuda, pero la forma en que lo veo es que el tipo que tienes en tu programa y los tipos que envías y recibes de Firestore son tipos diferentes.

Entonces, TypeScript tiene esta característica llamada 'Partial' que toma una interfaz y hace que todos los campos sean opcionales. De esa manera, incluso si el objeto no está completo, todavía cumplirá y te proporcionará intellisense.

Entonces, hago esto: export type dataUpdate<T>=Partial<T>;

Luego, hago: const userPayload: dataUpdate<User>=snapshot/typecase as User

Artículos relacionados