Home > OS >  TypeScript is not aware of the type of a destructured object
TypeScript is not aware of the type of a destructured object

Time:01-15

I'm making a basic Firebase call to retrieve a collection this way

import { getFirestore, collection, getDocs } from "firebase/firestore";

import { Invoice } from "../models/Invoice";

const db = getFirestore();

export const getInvoicesCollection = async () => {
  try {
    const snapshot = await getDocs(collection(db, "invoices"));

    const docs: Invoice[] = snapshot.docs.map((doc) => ({
      ...doc.data(),
    }));

    console.log(docs);
  } catch (error) {
    console.error(error);
  }
};

export default getInvoicesCollection;

The response object returned by Firebase is pretty fat so I map everything I need into a new one in this part:

const docs: Invoice[] = snapshot.docs.map((doc) => ({
  ...doc.data(),
}));

console.log(docs);

And I get the result in the browser:

enter image description here

But TypeScript complains that:

Type '{ [x: string]: any; }[]' is not assignable to type 'Invoice[]'.
Type '{ [x: string]: any; }' is missing the following properties from type 'Invoice': id, createdAt, paymentDue, description, and 8 more.

If I get it right, it says that my variable is an array of objects with a single property which is a string and can be anything? How can I make it aware of what the object really looks like?

CodePudding user response:

The type that doc.data() returns is { [x: string]: any; }, meaning an object with any number or properties with a string for a key, each of which can have any value. There's no way for typescript to figure out a more specific type than this, since the database could return pretty much anything.

So since typescript can't figure out the type, you will need to assert what the type is:

const docs: Invoice[] = snapshot.docs.map((doc) => ({
  ...doc.data() as Invoice,
}));

Note: by using a type assertion, you are telling typescript not to check your work, and just trust you. If you make a mistake and the database actually contains different types of objects, typescript won't be able to tell you about that.

  •  Tags:  
  • Related