Images has a wrong types attached to it
Describe the Bug.
Good evening please i have been getting wrong types when i use upload field type in payload
export interface Testimonial {
id: number;
quote: string;
name: string;
designation: string;
**src: number | Media;**
updatedAt: string;
createdAt: string;
}
I made emphasis on the src type generated for media in payload
it is gives me issue when i want to use typescript also i cant edit it cause it is generated everytime on a request is made to payload
Reproduction Steps
i created my schema like this one below import type { CollectionConfig } from "payload" import { Media } from "./Media"
export const CaseStudies: CollectionConfig = {
slug: "case-studies",
access: {
read: () => true,
},
fields: [
{
name: "title",
type: "text",
required: true,
},
{
name: "gallery",
type: "array",
fields: [
{
name: "image",
type: "upload",
relationTo: "media",
required: true,
},
],
},
{
name: "link",
type: "text",
},
{
name: "description",
type: "text",
},
],
}
payload config
// storage-adapter-import-placeholder
import { postgresAdapter } from "@payloadcms/db-postgres"
import { payloadCloudPlugin } from "@payloadcms/payload-cloud"
import { lexicalEditor } from "@payloadcms/richtext-lexical"
import path from "path"
import { buildConfig } from "payload"
import { fileURLToPath } from "url"
import sharp from "sharp"
import { uploadthingStorage } from "@payloadcms/storage-uploadthing"
import { Users } from "./collections/Users"
import { Media } from "./collections/Media"
import { CaseStudies } from "./collections/CaseStudies"
import { Brands } from "./collections/Brands"
import { Testimonials } from "./collections/Testimonials"
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
export default buildConfig({
admin: {
user: Users.slug,
importMap: {
baseDir: path.resolve(dirname),
},
},
collections: [Users, Media, CaseStudies, Brands, Testimonials],
editor: lexicalEditor(),
secret: process.env.PAYLOAD_SECRET || "",
typescript: {
outputFile: path.resolve(dirname, "payload-types.ts"),
},
db: postgresAdapter({
pool: {
connectionString: process.env.DATABASE_URI || "",
},
}),
sharp,
plugins: [
payloadCloudPlugin(),
// storage-adapter-placeholder
uploadthingStorage({
collections: {
media: true,
},
options: {
token: process.env.UPLOADTHING_TOKEN,
acl: "public-read",
},
}),
],
})
then i generate the type after put the schema in my payload config
types gotten are not useable
export interface Media {
id: number;
alt: string;
_key?: string | null;
updatedAt: string;
createdAt: string;
url?: string | null;
thumbnailURL?: string | null;
filename?: string | null;
mimeType?: string | null;
filesize?: number | null;
width?: number | null;
height?: number | null;
focalX?: number | null;
focalY?: number | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "case-studies".
*/
export interface CaseStudy {
id: number;
title: string;
gallery?:
| {
**image: number | Media;**
id?: string | null;
}[]
| null;
link?: string | null;
description?: string | null;
updatedAt: string;
createdAt: string;
}
then i make a request to my payload backend in the nextjs app ND i get this error
Type 'import("/workspace/port/src/payload-types").Testimonial[]' is not assignable to type 'Testimonial[]'.
Type 'import("/workspace/port/src/payload-types").Testimonial' is not assignable to type 'Testimonial'.
Types of property 'src' are incompatible.
Type 'number | Media' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.ts(2322)
animated-testimonials.tsx(18, 3): The expected type comes from property 'testimonials' which is declared here on type 'IntrinsicAttributes & { testimonials: Testimonial[]; autoplay?: boolean | undefined; }'
(property) testimonials: Testimonial[]
Environment Info
Node: 20.17.0
npm: 10.8.2
Yarn: 1.22.22
pnpm: 9.9.0
Relevant Packages:
payload: 3.0.2
next: 15.0.3
@payloadcms/db-postgres: 3.0.2
@payloadcms/email-nodemailer: 3.0.2
@payloadcms/graphql: 3.0.2
@payloadcms/next/utilities: 3.0.2
@payloadcms/payload-cloud: 3.0.2
@payloadcms/plugin-cloud-storage: 3.0.2
@payloadcms/richtext-lexical: 3.0.2
@payloadcms/storage-uploadthing: 3.0.2
@payloadcms/translations: 3.0.2
@payloadcms/ui/shared: 3.0.2
react: 19.0.0-rc-64f89510-20241119
react-dom: 19.0.0-rc-64f89510-20241119
Operating System:
Platform: linux
Arch: x64
Version: #202407021948 SMP PREEMPT_DYNAMIC Tue Jul 2 20:28:47 UTC 2024
Available memory (MB): 64298
Available CPU cores: 16
This issue has been marked as stale due to lack of activity.
To keep this issue open, please indicate that it is still relevant in a comment below.
Please the issue hasn't been resolved
On Fri, Dec 20, 2024, 6:05 AM github-actions[bot] @.***> wrote:
This issue has been marked as stale due to lack of activity.
To keep this issue open, please indicate that it is still relevant in a comment below.
— Reply to this email directly, view it on GitHub https://github.com/payloadcms/payload/issues/9549#issuecomment-2556294749, or unsubscribe https://github.com/notifications/unsubscribe-auth/A5RGP2XVE7IT5HSNMGID6JL2GOQQBAVCNFSM6AAAAABSRTZ3VOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKNJWGI4TINZUHE . You are receiving this because you authored the thread.Message ID: @.***>
I'm facing the same problem. The type for “uploads” is generated as number | Media;
Payload 3.9.0
It seems to be due to the depth property, because with a value of 0, the id will be returned.
Please can you fix this issue if you can tag them also
On Fri, Dec 20, 2024, 2:12 PM Michael @.***> wrote:
I'm facing the same problem. The type for “uploads” is generated as number | Media; Payload 3.9.0
— Reply to this email directly, view it on GitHub https://github.com/payloadcms/payload/issues/9549#issuecomment-2556978426, or unsubscribe https://github.com/notifications/unsubscribe-auth/A5RGP2U5DPT24QYDNLKJRSD2GQJUPAVCNFSM6AAAAABSRTZ3VOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKNJWHE3TQNBSGY . You are receiving this because you authored the thread.Message ID: @.***>
Still happening on 3.20. I think it might be specific to when the postgres adapter is in use.
Still happening on 3.20. I think it might be specific to when the postgres adapter is in use.
Confirmed. I tried the mongo adapter and it generated the correct types.
So the issue now is the postgres adapter which we are using, is there any solution cause I have check the docs several times but I couldn't find way to alter the type definition of the type being generated. At least there should be a guide for that not just a small section
On Mon, Feb 3, 2025, 2:42 PM Julian Paas @.***> wrote:
Still happening on 3.20. I think it might be specific to when the postgres adapter is in use.
Confirmed. I tried the mongo adapter and it generated the correct types.
— Reply to this email directly, view it on GitHub https://github.com/payloadcms/payload/issues/9549#issuecomment-2631041993, or unsubscribe https://github.com/notifications/unsubscribe-auth/A5RGP2WLKDNJLZHXNCRG4H32N5W5DAVCNFSM6AAAAABSRTZ3VOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMMZRGA2DCOJZGM . You are receiving this because you authored the thread.Message ID: @.***>
It's a pain in the ass, but it's not hard to work around. Any time you have a thing: number | Thing you just need to check if it's an id and then fetch the thing by its id.
const thing =
typeof thingOrId === "object"
? thingOrId
: await payload.findByID({
collection: "things",
id: thingOrId ,
});
Yeah, this is rather annoying.
I'm doing this at the moment, feels a bit grubby
import type { ImageProps } from 'next/image'
import type { Media } from '~/payload-types'
export function parseImage(image: (number | null) | Media | undefined) {
if (typeof image === 'number' || !image) return null
return {
src: image.url, // string | null | undefined
width: image.width, // number | null | undefined
height: image.height, // number | null | undefined
alt: image.alt, // string | null | undefined
} as ImageProps // eeeeee, this isn't ideal
}
it also means I have to do this every time i want to use an image, even though it's a required field
const image = parseImage(f.image)
return (
<Carousel.Item
value={0}
key={f.id}
className="w-full flex-shrink-0"
>
{image && <Image {...image} />}
<Stack className="gap-7 text-center">
<Text className="text-sm" weight="bold">
{instruction}
</Text>
<Text className="text-5xl" weight="bold">
{f.title}
</Text>
</Stack>
</Carousel.Item>
)
@magicspon i like this approach i just feel like it should be fixed in the future
ping
2 things:
- Those types are correct
- You either get the ID (number | string *for uuid) or the Media object depending on access control and query depth
A helpful person wrote this on the official Discord - https://discord.com/channels/967097582721572934/1377390470958809128 This also explains the issue.
Yeah those types are correct. Based on depth and access control we cannot guarantee that the type will be fulfilled so it has to be ID | DocumentType. You can use one of the options in this thread to ensure the document is fully expanded for usage.
This issue has been automatically locked. Please open a new issue if this issue persists with any additional detail.