P
Prisma2d ago
sharf

How to get proper type for relation from two different include queries.

I'm building a Next.js app for a personal project building a GUI for a sqlite db as a learning exercise. I opted for Prisma here and have been working my way through typing issues. A quick run down of my scheme: player with id and name, deck with id and name, game with id and datetime, anddeck_game with a bulk of the data (in hindsight, not a great name). deck_game has an id, a game_id, player_id, deck_id, and position. How this works is for each game that's played, I track what player was in it, what deck they had, and what position they finished in. So in a 4 player game I'd have 4 deck_game rows matching the game_id, with the player_id and deck_id matching their respective tables, and the position that player/deck finished in. For my app, I've made several Prisma calls with some complicated includes. The relevant ones for this question are fetchPlayer and fetchDecks. I've made some const and types to appease ESLint throughout as well. The relevant ones look like this:
export const playerInclude = {
deck: {
orderBy: {
name: 'asc'
},
include: {
deck_game: true,
player: true,
}
},
deck_game: {
include: {
game: {
include: {
deck_game: true
}
}
}
}
} satisfies Prisma.playerInclude

export const deckInclude = {
player: true,
deck_game: {
include: {
game: {
include: {
deck_game: true
}
}
}
}
} satisfies Prisma.deckInclude

export type PlayerWithDeckGame = Prisma.PromiseReturnType<typeof fetchPlayer>
export type DecksWithDeckGame = Prisma.PromiseReturnType<typeof fetchDecks>
export const playerInclude = {
deck: {
orderBy: {
name: 'asc'
},
include: {
deck_game: true,
player: true,
}
},
deck_game: {
include: {
game: {
include: {
deck_game: true
}
}
}
}
} satisfies Prisma.playerInclude

export const deckInclude = {
player: true,
deck_game: {
include: {
game: {
include: {
deck_game: true
}
}
}
}
} satisfies Prisma.deckInclude

export type PlayerWithDeckGame = Prisma.PromiseReturnType<typeof fetchPlayer>
export type DecksWithDeckGame = Prisma.PromiseReturnType<typeof fetchDecks>
The fetches are:
export const fetchPlayer = async (id: number) => {
return prisma.player.findUniqueOrThrow({
where: {
id: z.coerce.number().parse(id)
},
include: playerInclude
})
}
export const fetchDecks = async () => {
return prisma.deck.findMany({
orderBy: {
name: 'asc'
},
include: deckInclude
})
}
export const fetchPlayer = async (id: number) => {
return prisma.player.findUniqueOrThrow({
where: {
id: z.coerce.number().parse(id)
},
include: playerInclude
})
}
export const fetchDecks = async () => {
return prisma.deck.findMany({
orderBy: {
name: 'asc'
},
include: deckInclude
})
}
My issue lies in a component that accepts a collection decks, which have deck_game > game > deck_game. To explain the relations a bit more, each deck has multiple deck_game rows, one for each game it's been in. Then each row has an associated game but I then need each deck_game row that's associate with that game to do comparisons for stats. That's where the DecksWithDeckGame type comes in. This comoponent accepts a collection of decks:
export function DeckTable({ decks, showPlayers }: {
decks: DecksWithDeckGame,
showPlayers?: boolean,
}) {
export function DeckTable({ decks, showPlayers }: {
decks: DecksWithDeckGame,
showPlayers?: boolean,
}) {
My issue is that when I pass in decks from the fetchDecks() query everything works. But passing in the player.deck from fetchPlayer() I get a "type is not assignable to type" error. Even though the decks have an identical structure, because the player deck comes from a different fetch call, the type is not the same. How would I create a type that matches the deck_game from both fetchDecks() and fetchPlayer? For my little app I absolutely could use multiple queries to get the data in the same manner for both components, but for the sake of learning I wanted to use this approach, which would be more efficient at scale. That said, I may be going about these relations/queries all wrong so please let me know if there's a better approach! Thank you.
1 Reply
Prisma AI Help
You decided to hold for human wisdom. We'll chime in soon! Meanwhile, #ask-ai is there if you need a quick second opinion.

Did you find this page helpful?