Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

TypeScript is not aware of the type of a destructured object

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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?

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading