Adding fields to a templated `select`

Hi, Let's say I have a getUser function, which takes a select as its argument :
const getUser = async <T extends Prisma.UserSelect>(select: T) => {
return await prisma.user.findFirst({select})
}
const getUser = async <T extends Prisma.UserSelect>(select: T) => {
return await prisma.user.findFirst({select})
}
Now I want to add a log that says which user I'm getting, so I try this :
const getUser = async <T extends Prisma.UserSelect>(select: T) => {
const user = await prisma.user.findFirst({
select: {...select, id: true},
})
console.log(`Getting user ${user.id}`)
return user
}
const getUser = async <T extends Prisma.UserSelect>(select: T) => {
const user = await prisma.user.findFirst({
select: {...select, id: true},
})
console.log(`Getting user ${user.id}`)
return user
}
But now I have the following TypeScript error: Type 'T & { id: true; }' is not assignable to type 'T & { id: true; }'. Two different types with this name exist, but they are unrelated. So I found the workaround of creating a variable for the select :
const getUser = async <T extends Prisma.UserSelect>(select: T) => {
const selectWithId = {...select, id: true}
const user = await prisma.user.findFirst({select: selectWithId})
console.log(`Getting user ${user.id}`)
return user
}
const getUser = async <T extends Prisma.UserSelect>(select: T) => {
const selectWithId = {...select, id: true}
const user = await prisma.user.findFirst({select: selectWithId})
console.log(`Getting user ${user.id}`)
return user
}
That gets rid of the previous error, but I still have an error on the user.id : Property 'id' does not exist on type GIANT_TYPESCRIPT_TYPE. Is there a workaround for this? Adding fields to a templated select is a use-case that came up a few times already in my codebase so I'm trying to find a proper solution (right now we just slap an any on there). Thank you
3 Replies
moosthuizen
moosthuizen2mo ago
@Baptiste Marchand I'm trying to recreate, but no errors on my side:
const selectFirstSite = async <T extends Prisma.MSiteSelect>(select: T) => {
const select2 = { ...select, id: true };
const site = await db.mSite.findFirst({
select: select2,
});
console.log(site);
return site;
};
const selectFirstSite = async <T extends Prisma.MSiteSelect>(select: T) => {
const select2 = { ...select, id: true };
const site = await db.mSite.findFirst({
select: select2,
});
console.log(site);
return site;
};
Baptiste Marchand
@moosthuizen Can you do console.log(site.id) instead ? That's the part that is breaking for me
moosthuizen
moosthuizen2mo ago
Ahh, I'm with you. Will try later and let you know if I figure it out