Prisma är en lättanvänd ORM med riktigt användbara Typescript-typer som ändrar resultattypen för en fråga baserat på de alternativ du skickar in.
När du bygger ut en applikation kommer du utan tvekan att stöta på en situation där du vill slå in en befintlig Prisma-metod med anpassad logik. Du kan välja att passera igenom typerna så att den som ringer kan bestämma om de vill utöka frågan.
Om du använder Prismas frågeargument förväntar du dig också att få Prismas returtyper.
Detta är inte så lätt som det låter, eftersom att bara skicka data (eller till och med skicka ett generiskt säkerhetskopierat värde) inte fungerar som avsett.
Du kan börja med att prova något sånt här. Slå in uppgiften findMany
anrop med en funktion som accepterar Prisma query args, men modifierar frågan för att göra något specifikt.
// DOES NOT WORK
specialFindMany<T extends Prisma.TodoFindManyArgs>(args?:T){
return prisma.todo.findMany({
...args,
where:{
...args?.where
isSpecial: true
}
})
}
Detta ger typfel.
Upptäckt
Som med allt annat i Typescript, om du gräver i typerna kan du få fram vad en funktion faktiskt förväntar sig.
Tittar på typerna för todo.findMany()
från och med Prisma 2.24.0
du hittar något som ser ut så här:
findMany<T extends TodoFindManyArgs>(
args?: SelectSubset<T, TodoFindManyArgs>
): CheckSelect<T, PrismaPromise<Array<Todo>>, PrismaPromise<Array<TodoGetPayload<T>>>>
Du kan se att de hämtar typen från SelectSubset
s generika.
Lösning
Om du kopierar denna typ till både din metods deklaration och prisma.finyMany
generisk får du en fungerande maskinskriven passthrough.
async specialFindMany<T extends Prisma.TodoFindManyArgs>(
args?: Prisma.SelectSubset<T, Prisma.TodoFindManyArgs>,
) ){
// Other custom logic
const result = await prisma.todo.findMany<
Prisma.SelectSubset<T, Prisma.SearchFindManyArgs>>(
{
...args!,
where:{
...args?.where
isSpecial: true
}
})
// Other custom logic
return result
}
Utan att skicka in generiken kommer typerna fortfarande att misslyckas (åtminstone i mina tester).
Eftersom args är valfritt kommer typerna att klaga på att tvinga igenom ett objekt. Det kan finnas en bättre lösning på detta, men jag !
tvingade args-typen att existera.
Slutsats
Det här känns ganska besvärligt, och jag skulle gärna se lite mer flexibelt skrivande i Prisma, men det får jobbet gjort för att slå in databasanrop.
Den här lösningen täcker tyvärr inte utökning av de typer som ingår i Prisma-anropet, så inklusive include
eller select
kommer inte att resultera i korrekta utdatatyper.
Om du har en bättre lösning, låt mig veta i kommentarerna!!!