P
Prisma•3d ago
Florian

Composing relation types

How do ya'll set up your relation types? I currently have one big type that includes all relations:
export type ProjectData = Prisma.ProjectGetPayload<{
include: {
tasks: true;
attachments: { include: { user: true } };
members: { include: { user: true } };
_count: { select: { comments: true; attachments: true } };
};
}>;
export type ProjectData = Prisma.ProjectGetPayload<{
include: {
tasks: true;
attachments: { include: { user: true } };
members: { include: { user: true } };
_count: { select: { comments: true; attachments: true } };
};
}>;
But some in places I only use a subset of these values. I assume I should split that up. But what then? Do you create combinations of types like type ProjectWithTasksAndAttachments = ProjectWithTasks & ProjectWithAttachments? What's your approach?
3 Replies
Prisma AI Help
Prisma AI Help•3d ago
You've gone full bot mode! Let me fetch that AI answer for you ASAP. Your question about composing relation types in Prisma is a common one. There are a few approaches you can take to handle this situation more efficiently. Let me outline some options based on the information from our knowledge sources: 1. Using Prisma's utility types: Instead of creating one large type with all relations, you can use Prisma's utility types to create more specific types as needed. This approach is described in the Prisma documentation on operating against partial structures of model types. For example:
type ProjectWithTasks = Prisma.ProjectGetPayload<{
include: { tasks: true }
}>;

type ProjectWithAttachments = Prisma.ProjectGetPayload<{
include: { attachments: { include: { user: true } } }
}>;

type ProjectWithTasksAndAttachments = Prisma.ProjectGetPayload<{
include: {
tasks: true,
attachments: { include: { user: true } }
}
}>;

type ProjectWithTasks = Prisma.ProjectGetPayload<{
include: { tasks: true }
}>;

type ProjectWithAttachments = Prisma.ProjectGetPayload<{
include: { attachments: { include: { user: true } } }
}>;

type ProjectWithTasksAndAttachments = Prisma.ProjectGetPayload<{
include: {
tasks: true,
attachments: { include: { user: true } }
}
}>;

This approach allows you to create specific types for different combinations of relations without manually combining them. 2. Using TypeScript's utility types: As suggested in a GitHub discussion about partial types, you can use TypeScript's utility types like Pick or intersection types to create combinations:
type ProjectWithTasksAndAttachments = ProjectWithTasks & ProjectWithAttachments;

type ProjectWithTasksAndAttachments = ProjectWithTasks & ProjectWithAttachments;

This approach can be useful for simpler combinations, but it might become less readable for more complex structures. 3. Using Prisma's validator: If you prefer a more declarative approach, you can use Prisma's validator as shown in the Prisma documentation:
const projectWithTasks = Prisma.validator<Prisma.Project
DefaultArgs>()({
include: { tasks: true },
});

type ProjectWithTasks = Prisma.ProjectGetPayload<typeof projectWithTasks>;

const projectWithTasks = Prisma.validator<Prisma.Project
DefaultArgs>()({
include: { tasks: true },
});

type ProjectWithTasks = Prisma.ProjectGetPayload<typeof projectWithTasks>;

This method can be particularly useful when dealing with complex nested relations. The best approach depends on your specific use case and personal preference. If you're dealing with many different combinations of relations, using Prisma's utility types (option 1) might be the most flexible and maintainable solution. It allows you to create specific types as needed without manually combining them. Remember, the goal is to balance type safety with code readability and maintainability. Choose the approach that best fits your project's needs and your team's preferences. 🤔 Alright, thanks for letting us know that there's still some help needed. A team member will reply to you shortly. In the meantime, please let us know any additional info, questions, or which parts of the answer may need clarification.
Nurul
Nurul•3d ago
Operating against partial structures of your model types | Prisma D...
This page documents various scenarios for using the generated types from the Prisma namespace
Florian
FlorianOP•2d ago
Thank you for your answer. My question is not how to generate the type, but best practices for composing them. In your link, let's say in some places you need UserWithPosts, in others UserPersonalData, and then in some places you need both. How do you handle that? Do you make a UserWithPostsAndPersonalData? It seems like this can get out of hand fast.

Did you find this page helpful?