Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

PayloadCMS 3.0 Typescript returning Related collection as Type or Number.

default discord avatar
qubica.10 months ago
8

(property) User.events?: {


relationTo: "events";


value: number | Event;


}[] | null | undefined



I can't figure out why Typescript would return a number.


Because of this I have to add a typeguard in my code.



user.events?.map((event) => {


if (typeof event.value === 'number') {


// uhh, why can it be a number?


} else {


// ... Correct event values


}


});



Would love explore better solutions. All help is appreciated.

  • discord user avatar
    denolfe
    10 months ago

    Provide your payload config code for events

  • default discord avatar
    qubica.10 months ago

    Yes, here you go:



    import { isAdmin } from '@/access/isAdmin'
    import { isAdminOrHasEventAccess } from '@/access/isAdminOrHasEventAccess'
    import { CollectionConfig } from 'payload/types'
    
    export const Events: CollectionConfig = {
      slug: 'events',
      admin: {
        useAsTitle: 'title',
      },
      versions: {
        maxPerDoc: 100,
        drafts: true,
      },
      access: {
        create: isAdmin,
        read: isAdminOrHasEventAccess('id'),
        update: isAdmin,
        delete: isAdmin,
      },
      fields: [
        {
          name: 'title',
          type: 'text',
          required: true,
        },
        {
          name: 'slug',
          type: 'text',
          unique: true,
          required: true,
        },
        {
          name: 'playlists',
          label: 'Playlists',
          type: 'array',
          fields: [
            {
              name: 'playlist',
              type: 'relationship',
              relationTo: ['playlists'],
            },
          ],
          admin: {
            initCollapsed: true,
          },
        },
      ],
    }

    Thank you for looking into it.

  • discord user avatar
    denolfe
    10 months ago

    So this is a common confusion with relationships. If you were to query your users with

    depth=0

    , events would come back

    as an id

    , not an event. The type reflects this possibility.

  • default discord avatar
    qubica.10 months ago

    Thank you for the help, I'll def check this out.

  • default discord avatar
    plaguefps9 months ago

    This is extremely annoying (only because it seems to require more advanced type narrowing than originally expected), any suggestions for how we should combat this?

  • discord user avatar
    denolfe
    9 months ago

    Proper type narrowing is the way for now

  • default discord avatar
    plaguefps9 months ago

    Yeah works as expected with that in place, although I will admit the type narrowing specifically for this situation seems to be more advanced than usual in order to achieve the expected result.



    In the past when I compared a non-object type to an object type I could do something as simple as:



    if ('property' in object) return object

    and you would receive whatever type that object is, however in this case I had to do something like this to get my expected result:



     
    const isRelation = <T extends { id: string | number }>(value: number | T): value is T => {
      return (value as T).id !== undefined;
    }
    
    
    export const resolveRelation = <T extends { id : string | number }>(value: number | T) => {
      if (isRelation(value)) return value
    }


    I don't suppose you may have a theory as to why?



    I just found it interesting as the type seemed so simple being either a number or some object interface, yet it required some more advanced type narrowing.

  • discord user avatar
    denolfe
    9 months ago

    Using typeof number or typeof string tends to be easier in my experience

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.