Is there a way to implement a function that takes a Prisma object and dynamically sets the return type based on the included relations?
I am aiming to type versionWithRelations
with properties like pages
, variables
, and actions
, while versionWithoutRelations
should not have those properties.
Below is my initial approach:
import { Prisma } from "@prisma/client";
const getVersion = <
Relations extends Prisma.AppVersionInclude,
App extends Prisma.AppGetPayload<{
include: { versions: { include: Relations } };
}>,
>(
app: App,
): Prisma.AppVersionGetPayload<{ include: Relations }> => {
return app.versions[0]!;
};
const withRelations = await prisma.app.findUnique({
where: { id: "foo" },
include: {
versions: {
include: {
pages: true,
variables: true,
actions: true,
},
},
},
});
const withoutRelations = await prisma.app.findUnique({
where: { id: "foo" },
include: {
versions: true,
},
});
const versionWithRelations = getVersion(withRelations!);
const versionWithoutRelations = getVersion(withoutRelations!);
// Expected types:
// typeof versionWithRelations
type VersionWithRelations = {
id: string;
appId: string;
majorVersion: number;
minorVersion: number;
patchVersion: number;
pages: {
id: string;
appVersionId: string;
path: string;
description: string;
}[];
variables: {
id: string;
appVersionId: string;
name: string;
description: string;
}[];
actions: {
id: string;
appVersionId: string;
name: string;
description: string;
}[];
}
// typeof versionWithoutRelations
type VersionWithoutRelations = {
id: string;
appId: string;
majorVersion: number;
minorVersion: number;
patchVersion: number;
}
Here is my Prisma schema definition:
model App {
id String @id @default(cuid())
name String
versions AppVersion[]
}
model AppVersion {
id String @id @default(cuid())
appId String
majorVersion Int
minorVersion Int
patchVersion Int
pages AppPage[]
variables AppVariable[]
actions AppAction[]
app App @relation(fields: [appId], references: [id], onDelete: Cascade)
@@unique([appId, majorVersion, minorVersion, patchVersion])
}
model AppPage {
id String @id @default(cuid())
appVersionId String
path String
description String
appVersion AppVersion @relation(fields: [appVersionId], references: [id], onDelete: Cascade)
@@unique([appVersionId, path])
}
model AppVariable {
id String @id @default(cuid())
appVersionId String
name String
description String
appVersion AppVersion @relation(fields: [appVersionId], references: [id], onDelete: Cascade)
@@unique([appVersionId, name])
}
model AppAction {
id String @id @default(cuid())
appVersionId String
name String
description String
appVersion AppVersion @relation(fields: [appVersionId], references: [id], onDelete: Cascade)
@@unique([appVersionId, name])
}