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.

How to avoid type errors in nested collections

default discord avatar
swheeler39_98030last year
4

Hi all this is probably a pretty basic answer but i'm not great with typescript and having some trouble. When using the local API to fetch data from a collection that has a relationship field I am getting type errors when accessing any fields within the relationship collection. For example if I have an "assignments" collection with an "assigned_to" field that is a relationship field pointing to my "users" collection I want to be able to access the users name with "assignments.assigned_to.name". This works fine but I am getting a type error: "Property name does not exist on type number | User". Is there some way to make it clear that the type is User and not number? I know I can do something like:



const user = assignment.assigned_to as unknown as User


const user_name = user.name



Or even jus use ts-ignore, but that doesnt feel like best practice so wondering what others do to handle this? Thanks for any assistance!

  • default discord avatar
    heed17last year

    That's because PayloadCMS gives you the data as you request it, and you do so through the GET endpoints for each collection. When you make a GET request, you can specify the depth (even with the local API). If the depth is 0, it will fetch only the fields of that entry, and no nested objects. So, for relation fields, it will fetch only the ID.



    In theory it's not possible to avoid this error... but... If you are certain of the depth of the response (e.g. you specified depth: 1), you can avoid that error using: assignment.assigned_to as User



    But remember, this is just in case you are certain of it. There are some scenarios where you cannot access nested objects even if you request them (e.g. when you have no access to read that user).



    For me, I try to always use the ID. If I need to read the name of nested users, you can define a hook that takes the names of all the students, then group them into an array of strings, and add that array to the final response using the afterRead hooks property. This is a safe manner to show the names while protecting the access control policies.

  • default discord avatar
    zed0547last year

    Hey

    @263471686979026945

    &

    @1166422021526261811

    ,



    So the above comment is almost there! However, technically speaking, the correct answer would be to use Javascripts' inherent type casting/checking system. The way you can determine a value is either User or number is as follows:



    typeof myUser === 'number'


    You could of course also do the opposite and negate the equality check to see if the user is

    not

    a number. Just keep in mind, in Typescript, doing something like

    myUser as unknown as User

    is generally an anti-pattern and should be avoided. Generally speaking, try your best not to use

    as

    as much as possible.

  • default discord avatar
    heed17last year

    Thank you

    @654031862146007055

    , I'd like to share what I use in my projects



    type Entity = { id: string; } const getIdFromEntity = <T extends Entity>(entity: T | string) => { if (typeof entity === 'string') { return entity; } return entity.id; } export default getIdFromEntity;
  • default discord avatar
    swheeler39_98030last year

    Thanks everyone for responding, this is all very helpful!

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.