Complicated recursive types for self-relations in prisma models...

Prisma documentation says that types only contain the model's scalar fields, but doesn't account for any relations, thus you must use GetPayload. Prisma Model:
model Category {
id String @id @default(cuid())
name String? @unique
parent Category? @relation("CategoryToCategory", fields: [parentId], references: [id])
parentId String?
children Category[] @relation("CategoryToCategory")
}
model Category {
id String @id @default(cuid())
name String? @unique
parent Category? @relation("CategoryToCategory", fields: [parentId], references: [id])
parentId String?
children Category[] @relation("CategoryToCategory")
}
Default type produced:
type Category = {
id: string;
name: string | null;
parentId: string | null;
}
type Category = {
id: string;
name: string | null;
parentId: string | null;
}
Modified with GetPayload
type CategoryWithRelations = Prisma.CategoryGetPayload<{
include: {
parent: true;
children: true;
};
}>;
type CategoryWithRelations = Prisma.CategoryGetPayload<{
include: {
parent: true;
children: true;
};
}>;
which just means:
type CategoryWithRelations = Category & {
parent: Category | null;
children: Category[]
}
type CategoryWithRelations = Category & {
parent: Category | null;
children: Category[]
}
But children isn't recursive in this type ^^^ because it doesn't contain relations right? Correct way? Default type produced:
type Category = {
id: string;
name: string | null;
parentId: string | null;
}
type Category = {
id: string;
name: string | null;
parentId: string | null;
}
Modified with GetPayload
type CategoryWithRelations = Prisma.CategoryGetPayload<{
include: {
parent: true;
};
}>;
type CategoryWithRelations = Prisma.CategoryGetPayload<{
include: {
parent: true;
};
}>;
Recursive - Is this the right way?
type CategoryWithRelationsRecursive = CategoryWithRelations & {
children: CategoryWithRelations[]
}
type CategoryWithRelationsRecursive = CategoryWithRelations & {
children: CategoryWithRelations[]
}
3 Replies
jix74
jix74OP3y ago
I'm recursively mapping through my categories via:
function transform(
data: CategoryWithRelationsRecursive[],
path: string[] = []
): FlatCategory[] {
return data?.flatMap(({ id, name, children }) => {
const newPath = [...path, name];
return [
{ name: newPath.join(" > "), lastChildId: id },
...transform(children, newPath),
];
});
}
function transform(
data: CategoryWithRelationsRecursive[],
path: string[] = []
): FlatCategory[] {
return data?.flatMap(({ id, name, children }) => {
const newPath = [...path, name];
return [
{ name: newPath.join(" > "), lastChildId: id },
...transform(children, newPath),
];
});
}
And my function keeps getting the following typescript error
(parameter) children: (Category & {
parent: Category | null;
})[]

Argument of type
'(Category & { parent: Category | null; })[]'
is not assignable to parameter of type 'CategoryWithRelationsRecursive'.

Type '(Category & { parent: Category | null; })[]' is missing the following properties from type 'Category': id, name, parentId.
(parameter) children: (Category & {
parent: Category | null;
})[]

Argument of type
'(Category & { parent: Category | null; })[]'
is not assignable to parameter of type 'CategoryWithRelationsRecursive'.

Type '(Category & { parent: Category | null; })[]' is missing the following properties from type 'Category': id, name, parentId.
Leonidas
Leonidas3y ago
The error message says that you cannot assign a single element of your „Category“ to an field which is typed to be an array of this element In your type definition of CategoryWithRelations you typed parent to be an array - which does not seem to match your prisma schema.
jix74
jix74OP3y ago
I managed to fix all my type errors by re-defining a new type with manually-created relational properties and just making those relational properties equal to an array or single instance of the type (rather than the default prisma type that only contains scalar fields). Then I used type assertion on the data I received back from my trpc fetch to this new type. I'm now getting an error that says the ...transform part of my function is undefined. Such a headache...

Did you find this page helpful?