Improving typings of depth
in collections
#6161
Replies: 3 comments
-
Hey there - a solid fix here is super important for sure, but it's more complicated than depth alone unfortunately. For example, you might have access control that prevents a user from reading a document - or, in MongoDB at least, you might have deleted a document which will then prevent the document from populating successfully. Basically - this problem runs a bit deeper than solely being based on depth alone. But I agree, something needs to be done here. We will figure out a solution one way or another. Will bring this forward in our priorities list. |
Beta Was this translation helpful? Give feedback.
-
Hi. As a dirty fixe, I generate type in a file named import type * as PL from './payload-types-raw'
type ElementType<T> = T extends (infer U)[] ? U : never;
type TransformType<T> = {
[K in keyof T]: K extends "layout" ? TransformType<ElementType<T[K]>>[] : T[K] extends number | infer U ? U : TransformType<T[K]>
}
type TransformCollection<T> = {
[K in keyof T]: TransformType<T[K]>
}
export type Config = {
globals: PL.Config['globals']
collections: TransformCollection<PL.Config['collections']>
}
export type Page = TransformType<PL.Page>
<Export all your entities> At least it does the job for me (all my ids are number). I just suppose that, if there is an ID, the referenced object will always be present. |
Beta Was this translation helpful? Give feedback.
-
I recently ran into this with a poly relationship field, and had to ask on stack overflow. jcalz provided a thourough and great answer. I have copied it here for posterity One problem you're having is that TypeScript does not synthesize union types during inference of generic type arguments. When you call a function of the form Of course nothing stops you from explicitly specifying the type argument, like this:
That works, but... the output type isn't really what you want, is it? The resulting array has no idea that
Ideally you want Here's one approach:
where
using the
well, it's hard to see what type that is, so we can use something like https://stackoverflow.com/q/57683303/2887218 to show us:
Hooray! Unfortunately, this does not distribute over unions in
We lost
Now we get the right type for
Once we use a conditional type like this it's a little bit easier to use
But that's the same thing. So that type is what we want, mostly... except, we can't directly use it:
Oops, TypeScript can't tell that
but while conceptually that's right, intersection tends to have some weird effects:
That
That works, and
So let's build in that
which is really just splitting a union into members, doing an "identity" mapped type over each member, and pushing the union together again. We want to put that inline, and it should be inside the
and
That looks like what we wanted. The type of |
Beta Was this translation helpful? Give feedback.
-
Right now, Payload types does not have the concept of depth-aware types. For a typical collection, when a relationship type is generated into the schema, it hints
RelatedEntity | number
(orstring
depending on your ID type). This isn't useful behaviour for the consumers as they now need to either cast the variable toRelatedEntity
to get type completion or do some type guard checks to make sure the variable resolved toRelatedEntity
.I'm not sure how this can be improved in TypeScript but just throwing this out there.
Beta Was this translation helpful? Give feedback.
All reactions