Next.js Discord

Discord Forum

TypeScript Error: Type 'any[] | undefined' is not assignable to type 'Project[]

Answered
Collared Plover posted this in #help-forum
Open in Discord
Collared PloverOP
I'm encountering a TypeScript error in my code and need some assistance. The error message is: "Type 'any[] | undefined' is not assignable to type 'Project[]'. Type 'undefined' is not assignable to type 'Project[]'." This error occurs in the context of fetching data from two asynchronous functions (fetchProjects and fetchFeaturedProjects) and returning the results as part of a Promise. I've tried various approaches to handle this error, including checking for undefined values and ensuring that the returned data matches the expected type, but I'm still unable to resolve it. Any insights or suggestions on how to fix this issue would be greatly appreciated. Thank you!
Answered by Anay-208
Here, replace Project with Project[]
View full answer

66 Replies

Collared PloverOP
@Anay-208
async function getData(): Promise<{
  projectsdata: Project[];
  featuredProjectsData: Project[];
}> {
  try {
    // Execute both fetch functions concurrently
    const [projectsResult, featuredProjectsResult] = await Promise.all([
      fetchProjects(),
      fetchFeaturedProjects(),
    ]);

    // Destructure results
    const { result: projectsdata, error: projectsError } = projectsResult;
    const { result: featuredProjectsData, error: featuredProjectsError } =
      featuredProjectsResult;

    if (projectsError || featuredProjectsError) {
      // If there's an error in any of the fetch functions, throw an error
      throw new Error("Failed to fetch data");
    }

    // Return the data
    return { projectsdata, featuredProjectsData };
  } catch (error) {
    console.error("Error fetching data:", error);
    // Return empty arrays if there's an error
    return { projectsdata: [], featuredProjectsData: [] };
  }
}
@Anay-208 You've to add a type to the object you're passing
Collared PloverOP
async function getData(): Promise<{
  projectsdata: any;
  featuredProjectsData: any;
}> {
  try {
    // Execute both fetch functions concurrently
    const [projectsResult, featuredProjectsResult] = await Promise.all([
      fetchProjects(),
      fetchFeaturedProjects(),
    ]);

    // Destructure results
    const { result: projectsdata, error: projectsError } = projectsResult;
    const { result: featuredProjectsData, error: featuredProjectsError } =
      featuredProjectsResult;

    if (projectsError || featuredProjectsError) {
      // If there's an error in any of the fetch functions, throw an error
      throw new Error("Failed to fetch data");
    }

    // Return the data
    return { projectsdata, featuredProjectsData };
  } catch (error) {
    console.error("Error fetching data:", error);
    // Return empty arrays if there's an error
    return { projectsdata: [], featuredProjectsData: [] };
  }
}

export default async function Page() {
  const { projectsdata, featuredProjectsData } = await getData();

  return (
    <>
      <main className="w-full mb-16 flex items-center justify-center overflow-clip dark:text-light">
        <Layout className="px-0 xs:pt-10">
        ...................................
        <article className="mt-20 grid w-full grid-cols-12  gap-16 xl:gap-8 lg:gap-0 lg:gap-y-8 md:gap-0 sm:gap-0 xs:gap-0 md:!gap-y-8">
          <RecentProjects projects={projectsdata} />
          <FeaturedProjects projects={featuredProjectsData} />
        </article>
;
@Anay-208 you can send the code where this function is being executed
Collared PloverOP
Adding type "any" fixed the issue, but why didn't the initial type work? Since the data is identical, shouldn't it be able to use the same type?
Collared PloverOP
import { Project } from "../lib/definitions";

async function getData(): Promise<{
  projectsdata: Project[];
  featuredProjectsData: Project[];
}> {
  try {
    // Execute both fetch functions concurrently
    const [projectsResult, featuredProjectsResult] = await Promise.all([
      fetchProjects(),
      fetchFeaturedProjects(),
    ]);

    // Destructure results
    const { result: projectsdata, error: projectsError } = projectsResult;
    const { result: featuredProjectsData, error: featuredProjectsError } =
      featuredProjectsResult;

    if (projectsError || featuredProjectsError) {
      // If there's an error in any of the fetch functions, throw an error
      throw new Error("Failed to fetch data");
    }

    // Return the data
    return { projectsdata, featuredProjectsData };
  } catch (error) {
    console.error("Error fetching data:", error);
    // Return empty arrays if there's an error
    return { projectsdata: [], featuredProjectsData: [] };
  }
}
;
@Anay-208 It has a type of any or undefined
Collared PloverOP
If the type is the same, for example, I'm importing a type and using it for both, why is the data unidentical? Since these functions return identical objects.
Collared PloverOP
Can you showcase a simple example of what you mean?
So @Collared Plover, So here's a example.

If I run this getData() function from another file,
This is the error:
function.ts:13:11 - error TS2322: Type 'unknown' is not assignable to type 'ReturnType'.

13     const data : ReturnType = await (await fetch('https://jsonplaceholder.typicode.com/todos/1')).json();
             
To fix this, I need to add as ReturnType after the fetch, so line will be this:
  const data: ReturnType = await (
    await fetch("https://jsonplaceholder.typicode.com/todos/1")
  ).json() as ReturnType;
it tells the compiler that this function is returning ReturnType type
And thus, preventing errors
@Collared Plover
@Anay-208 <@1094891297187303494>
Collared PloverOP
import { Project } from "../lib/definitions";

async function getData(): Promise<{
  projectsdata: Project[];
  featuredProjectsData: Project[];
}> {
  try {
    // Execute both fetch functions concurrently
    const [projectsResult, featuredProjectsResult] = await Promise.all([
      fetchProjects() as Project[],
      fetchFeaturedProjects() as Project[],
    ]);

    // Destructure results
    const { result: projectsdata, error: projectsError } = projectsResult;
    const { result: featuredProjectsData, error: featuredProjectsError } =
      featuredProjectsResult;

    if (projectsError || featuredProjectsError) {
      // If there's an error in any of the fetch functions, throw an error
      throw new Error("Failed to fetch data");
    }

    // Return the data
    return { projectsdata, featuredProjectsData };
  } catch (error) {
    console.error("Error fetching data:", error);
    // Return empty arrays if there's an error
    return { projectsdata: [], featuredProjectsData: [] };
  }
}
;
if its not working, just send the error again
@Anay-208 if its not working, just send the error again
Collared PloverOP
Conversion of type 'Promise<{ result: any[]; error?: undefined; } | { error: string; result?: undefined; }>' to type 'Project[]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
Type 'Promise<{ result: any[]; error?: undefined; } | { error: string; result?: undefined; }>' is missing the following properties from type 'Project[]': length, pop, push, concat, and 35 more.ts(2352)
(alias) type Project = {
_id: Key | null | undefined;
type: string;
title: string;
github_link: string;
description: string;
image_url: StaticImageData;
}
@Anay-208 if its not working, just send the error again
Collared PloverOP
Also getting; Property 'result' does not exist on type 'Project[]'
Collared PloverOP
yes
@Collared Plover yes
Yup, thats the error. You've to convert the mongodb output toArray() or toObject()
@Anay-208 Yup, thats the error. You've to convert the mongodb output `toArray()` or `toObject()`
Collared PloverOP
I think I did such already. Have a look
@Anay-208 Yup, thats the error. You've to convert the mongodb output `toArray()` or `toObject()`
Collared PloverOP
export async function fetchProjects() {
  try {
    if (!project) await connectToCollection();
    if (!project) throw new Error("Projects not initialized.");

    const result = await project.find({}).limit(10).toArray();

    // Serialize the result into plain JSON objects
    const serializedResult = result.map((item) =>
      JSON.parse(JSON.stringify(item))
    );

    return { result: serializedResult };
  } catch (error) {
    console.error("Failed to fetch projects:", error);
    return { error: "Failed to fetch projects!" };
  }
}
@Anay-208 Yup, thats the error. You've to convert the mongodb output `toArray()` or `toObject()`
Collared PloverOP
Sent the wrong function, I edited it take a look again
@Anay-208 Maybe you need to edit line 5 to this: ts const { result } = await project.find({}).limit(10).toArray();
Collared PloverOP
Error: "Property 'result' does not exist on type 'WithId<Document>[]'.ts(2339)"
@Anay-208 its a error with the type mongodb is returning. try console.log projectsData, and featuredProjectsData here
Collared PloverOP
For example, I have a similar function for my Blog page, which has no errors:
@Anay-208 its a error with the type mongodb is returning. try console.log projectsData, and featuredProjectsData here
Collared PloverOP
async function getData(): Promise<Blog[]> {
  try {
    // Fetch projects data from your API or database
    const { result, error } = await fetchBlogs();

    if (error || !result) {
      // If there's an error or no result, throw an error to activate the error boundary
      throw new Error("Failed to fetch data");
    }

    // Return the projects data as props
    return result; // Assuming `result` is an array of projects data
  } catch (error) {
    // Catch any errors and log them
    console.error("Error fetching blogs:", error);

    // Return an empty object if there's an error
    return [];
  }
}
@Anay-208 and in `Promise.all`, you've mentioned that `projectsData` has the type `Project`
Collared PloverOP
async function getData(): Promise<{
  projectsdata: Project[];
  featuredProjectsData: Project[];
}> {
  try {
    // Execute both fetch functions concurrently
    const [projectsResult, featuredProjectsResult] = await Promise.all([
      fetchProjects(),
      fetchFeaturedProjects(),
    ]);

    // Destructure results
    const { result: projectsdata, error: projectsError } = projectsResult;
    const { result: featuredProjectsData, error: featuredProjectsError } =
      featuredProjectsResult;

    if (projectsError || featuredProjectsError) {
      // If there's an error in any of the fetch functions, throw an error
      throw new Error("Failed to fetch data");
    }

    // Return the data
    return { projectsdata, featuredProjectsData }; as {projectsData: Project, featuredProjectsData: Project}
  } catch (error) {
    console.error("Error fetching data:", error);
    // Return empty arrays if there's an error
    return { projectsdata: [], featuredProjectsData: [] };
  }
}

I'm getting Error: Unreachable code detected
@Anay-208 Try running the code first. And share screenshot of editor/ide
Collared PloverOP
./app/projects/page.tsx
Error: 
  × Expected ';', '}' or <eof>
    ╭─[C:\......................]
 27 │     }
 28 │ 
 29 │     // Return the data
 30 │     return { projectsdata, featuredProjectsData }; as {projectsData: Project, featuredProjectsData: Project}
    ·                                                    ─┬ ─
    ·                                                     ╰── This is the expression part of an expression statement
 31 │   } catch (error) {
 32 │     console.error("Error fetching data:", error);
 32 │     // Return empty arrays if there's an error
    ╰────

Caused by:
    Syntax Error
@Anay-208 Try running the code first. And share screenshot of editor/ide
Collared PloverOP
I got rid of the semicolon here:
return { projectsdata, featuredProjectsData }; as {projectsData: Project, featuredProjectsData: Project}
Collared PloverOP
Still getting errors;
Property 'projectsdata' is missing in type '{ projectsData: Project; featuredProjectsData: Project; }' but required in type '{ projectsdata: Project[]; featuredProjectsData: Project[]; }'.

Conversion of type '{ projectsdata: any[] | undefined; featuredProjectsData: any[] | undefined; }' to type '{ projectsData: Project; featuredProjectsData: Project; }' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Property 'projectsData' is missing in type '{ projectsdata: any[] | undefined; featuredProjectsData: any[] | undefined; }' but required in type '{ projectsData: Project; featuredProjectsData: Project; }'.

This expression is not callable.
  Type 'String' has no call signatures.
;
@Anay-208
@Anay-208 If issue is resolved, mark the message as a solution
Collared PloverOP
Here are my types:
export type Project = {
  _id: Key | null | undefined;

  type: string; // Define the type property as a string
  title: string; // Define the title property as a string
  github_link: string;
  description: string;
  image_url: StaticImageData;
};

export type Blog = {
  _id: Key | null | undefined;

  type: string; // Define the type property as a string
  title: string; // Define the title property as a string
  github_link: string;
  description: string;
  image_url: StaticImageData;
};
;
@Anay-208 Instead of projectsdata, use ProjectsData
Collared PloverOP
Did so
It should fix the error
@Anay-208 Instead of projectsdata, use ProjectsData
Collared PloverOP
Same error persists; I had been using "projectsdata" all along, so I renamed all occurrences to camel case.
@Anay-208 That just means there are still occurrences which use lowercase
Collared PloverOP
Projectsdata wasn't a mistake before; it was a consistent name I used. However, I've now changed it to camel case.
@Anay-208 The error is clearly states that you’re using lowercase projectsdata somewhere
Collared PloverOP
Oh i see what you mean now. now look at the new errors😆 :
Type '{ projectsData: Project; featuredProjectsData: Project; }' is not assignable to type '{ projectsData: Project[]; featuredProjectsData: Project[]; }'.
  Types of property 'projectsData' are incompatible.
    Type 'Project' is missing the following properties from type 'Project[]': length, pop, push, concat, and 35 more.

Conversion of type '{ projectsData: any[] | undefined; featuredProjectsData: any[] | undefined; }' to type '{ projectsData: Project; featuredProjectsData: Project; }' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Types of property 'projectsData' are incompatible.
    Type 'any[] | undefined' is not comparable to type 'Project'.
      Type 'any[]' is missing the following properties from type 'Project': _id, type, title, github_link, and 2 more.
;
Answer
I thought you’d understand
@Anay-208 I thought you’d understand
Collared PloverOP
You are way ahead of me; thanks the error is resolved.
@Anay-208 Mark my message as a solution
Collared PloverOP
:100vercel: