I have a relatively complex Prisma query which I use quite often with minor variations as part of larger queries. To simplify usages of this query, I made a function which takes an array of things to select as a parameter and returns the query.
function currentMetadataSelect(select: ("title" | "description" | "thumbnailUrl" | "createdAt")[]) {
return {
createdAt: select.includes("createdAt"),
proposedMetadata: {
select: {
metadata: {
select: {
title: select.includes("title"),
thumbnail: select.includes("thumbnailUrl") ? { select: { url: true } } : false,
description: select.includes("description")
}
}
},
...
}
};
}
However, regardless of what I pass to the function, the return type always evaluates to
{
createdAt: boolean,
proposedMetadata: {
select: {
metadata: {
select: {
title: boolean,
thumbnail: { select: { url: true } } | false,
description: boolean
}
}
},
...
}
}
```Which of course makes sense. However, this means that the return type of my Prisma queries isn't at all specific, and Prisma's great typing is the main reason I use it!
So, I tried the below code
```ts
type MetadataBit = "title" | "description" | "thumbnailUrl" | "createdAt";
type MetadataSelect<T extends MetadataBit[]> = {
createdAt: T[number] extends "createdAt" ? true : false;
proposedMetadata: {
select: {
metadata: {
select: {
title: T[number] extends "title" ? true : false;
thumbnail: T[number] extends "thumbnailUrl" ? { select: { url: true } } : false;
description: T[number] extends "description" ? true : false;
}
}
};
...
}
}
export function currentMetadataSelect<T extends MetadataBit[]>(select: T): MetadataSelect<T> {
return ... as MetadataSelect<T>;
}