withastro / astro

The web framework for content-driven websites. ⭐️ Star to support our work!
https://astro.build
Other
46.32k stars 2.45k forks source link

Typescript error for Content Collection: post with reference("tags") gives "No overload matches this call" #8450

Closed teinett closed 2 weeks ago

teinett commented 1 year ago

Astro Info

Astro                    v3.0.10
Node                     v18.17.0
System                   macOS (x64)
Package Manager          npm
Output                   server
Adapter                  @astrojs/node
Integrations             astro-compress

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

I have a page of one post and want to show all tags from this post: src/pages/posts/[slug].astro


---
export const prerender = true;

import type { CollectionEntry } from "astro:content";
import { getEntry, getEntries } from "astro:content";
import { getCollection } from "astro:content";

interface Props {
    post: CollectionEntry<"posts">;
}

const { post } = Astro.props;

export async function getStaticPaths() {
    const allPosts = await getCollection("posts");
    return allPosts.map((post) => ({
        params: { slug: post.slug },
        props: { post },
    }));
}

const { Content } = await post.render();

// get tags data from current post
const tags = await getEntries(post.data.tags);
...

---
...

I receive an error in VS Code:

No overload matches this call.
  Overload 1 of 2, '(entries: { collection: "tags"; slug: "black" | "red" | "white"; }[]): Promise<(({ id: "black.md"; slug: "black"; body: string; collection: "tags"; data: { cover?: { src: string; width: number; height: number; format: "png" | ... 5 more ... | "svg"; } | undefined; title: string; }; } & { ...; }) | ({ ...; } & { ...; }) | ({ ...; } & { ...; }))[]>', gave the following error.
  Overload 2 of 2, '(entries: { collection: never; id: string | number | symbol; }[]): Promise<never[]>', gave the following error.ts(2769)

Screenshot:

Снимок экрана 2023-09-07 в 08 51 30

What's the expected result?

I follow official docs: https://docs.astro.build/en/guides/content-collections/#accessing-referenced-data I expect to have no errors.

Link to Minimal Reproducible Example

https://github.com/teinett/learn-astro-images

Participation

natemoo-re commented 1 year ago

I'm guessing that post.data.tags is not being strictly typed? It looks like there is an | undefined in the type definition, which is probably what's causing this TypeScript error.

Not sure if we should widen our getEntries type to allow this loose behavior or if there's a way we can fix the post.data.tags typing.

DerTimonius commented 1 year ago

@natemoo-re I was looking into this and I'm not sure if there is a way to fix the typing of post.data.tags. It looks to me as if data is typed as Record<string, any> and I don't know if this could be changed safely. I would open a PR where I add undefined to getEntries with error handling if undefined is actually passed

bluwy commented 1 year ago

Would post.data.tags! fix it too? It's a bit odd that we loosen the type to allow undefined, and then we error in runtime again. If post.data.tags exists for sure, then the error should be fixed at the type-level first.

bonitoman commented 7 months ago

You missed to check if post is undefined, see example in doc https://docs.astro.build/en/guides/content-collections/#building-for-server-output-ssr

Try this:

const { post } = Astro.props;
if (post === undefined) {
  throw new Error("Post is required");    // or: return Astro.redirect('/');
}
ascorbic commented 4 months ago

Hi @teinett, I'm taking a look at this, but your reproduction repo no longer exists. If this is still a problem, could you create a new, minimal reproduction and I'll take a look. Thanks!

github-actions[bot] commented 4 months ago

Hello @teinett. Please provide a minimal reproduction using a GitHub repository or StackBlitz. Issues marked with needs repro will be closed if they have no activity within 3 days.

teinett commented 4 months ago

Hi @teinett, I'm taking a look at this, but your reproduction repo no longer exists. If this is still a problem, could you create a new, minimal reproduction and I'll take a look. Thanks!

Reproduction repo is public again: https://github.com/teinett/learn-astro-images

ascorbic commented 4 months ago

It looks like the issue is that tags is optional in the config, which means the type is nullable. If I remove optional() then the error goes away and the type is inferred correctly. I suppose getEntries could be expanded to allow undefined to be passed (and return undefined for that), but I think iot's probably better to keep the null check on the property itself when it's explicitly optional.

image

ascorbic commented 2 weeks ago

I think this is behaving as expected