cf-content-types-generator icon indicating copy to clipboard operation
cf-content-types-generator copied to clipboard

AssetLink / EntryLink types

Open dicash opened this issue 6 months ago • 5 comments

We generate contentful types for v10 as

source .env && cf-content-types-generator -X -s $CONTENTFUL_SPACE_ID  -t $CONTENTFUL_CM_TOKEN -o ./contentful

the produced types are:

import type { ChainModifiers, Entry, EntryFieldTypes, EntrySkeletonType, LocaleCode } from "contentful";
import type { TypeBlogAuthorSkeleton } from "./TypeBlogAuthor";
import type { TypeBlogCategorySkeleton } from "./TypeBlogCategory";

export interface TypeBlogArticleFields {
    slug?: EntryFieldTypes.Symbol;
    title?: EntryFieldTypes.Symbol;
    category: EntryFieldTypes.Array<EntryFieldTypes.EntryLink<TypeBlogCategorySkeleton>>;
    image?: EntryFieldTypes.AssetLink;
    summary?: EntryFieldTypes.Text;
    content?: EntryFieldTypes.RichText;
    author?: EntryFieldTypes.EntryLink<TypeBlogAuthorSkeleton>;
}

export type TypeBlogArticleSkeleton = EntrySkeletonType<TypeBlogArticleFields, "blogArticle">;
export type TypeBlogArticle<Modifiers extends ChainModifiers, Locales extends LocaleCode = LocaleCode> = Entry<TypeBlogArticleSkeleton, Modifiers, Locales>;

We use as as:

const articles = await client.getEntries<TypeBlogArticleSkeleton>({
    content_type: 'blogArticle',
    limit: 7,
  })
...
<Image src={articles.items[0].fields.image.file.url} />

the problem is with articles.items[0].fields.image.fields:

Property 'fields' does not exist on type 'UnresolvedLink<"Asset"> | Asset<undefined, string>'.
  Property 'fields' does not exist on type 'UnresolvedLink<"Asset">'

So how do you get access to internal image fields?

dicash avatar May 05 '25 15:05 dicash

Hey @dicash 👋

You should be able to to filter out unresolvable links by calling it with the right chain modifier:

const articles = await client.withoutUnresolvableLinks.getEntries<TypeBlogArticleSkeleton>({
    content_type: 'blogArticle',
    limit: 7,
  })

marcolink avatar May 05 '25 15:05 marcolink

Thank you @marcolink !

dicash avatar May 05 '25 15:05 dicash

A follow-up question, it seems to have a similar nature. It shows empty fields type for category:

const articles = await client.withoutUnresolvableLinks.getEntries<TypeBlogArticleSkeleton>({
    content_type: 'blogArticle',
    limit: 7,
    include: 4
  })
...
articles.items[0].fields.category[0]?.fields

Is there missing type somewhere?

dicash avatar May 05 '25 16:05 dicash

What do you mean by "empty" ? Have you checked if the entry specfic entry actually has data for category defined?

marcolink avatar May 05 '25 17:05 marcolink

The produced type for BlogCategory is:

import type {
  ChainModifiers,
  Entry,
  EntryFieldTypes,
  EntrySkeletonType,
  LocaleCode,
} from 'contentful'

export interface TypeBlogCategoryFields {
  slug?: EntryFieldTypes.Symbol
  name?: EntryFieldTypes.Symbol
  noindex?: EntryFieldTypes.Boolean
}

export type TypeBlogCategorySkeleton = EntrySkeletonType<TypeBlogCategoryFields, 'blogCategory'>
export type TypeBlogCategory<
  Modifiers extends ChainModifiers,
  Locales extends LocaleCode = LocaleCode
> = Entry<TypeBlogCategorySkeleton, Modifiers, Locales>

dicash avatar May 06 '25 13:05 dicash