Prisma/Typescript: how to extend client?

Viewed 61

I implemented such class:

import { PrismaClient } from '@prisma/client';

export type NotStartsWith<
  S,
  Prefix extends string,
> = S extends `${Prefix}${infer _X}` ? never : S;

export class DatabaseService extends PrismaClient {
  async $findPaginated<
    M extends NotStartsWith<keyof DatabaseService, '$'>,
    A extends Parameters<DatabaseService[M]['findMany']>[0],
  >(model: M, args?: A) {
    const data = await this[model].findMany(args);
    return {
      page: 1,
      results: data,
      total: 1,
      totalPages: 1,
    };
  }
}

Let's assume I have models post and user.

The real implementation is not important. But typescript gives me this error on the findMany call:

This expression is not callable. Each member of the union type 'x | y | z' has signatures, but none of those signatures are compatible with each other.

I think it means that somehow I could call the findMany of user with arguments of post. But it is not possible since it is all well typed. If I change to (this[model] as any) to compile and type my new function with first argument post, the second argument's properties are correctly autocompleted for the model post.

So I don't get why I can't fully type my function.

Also, this is not an optimal extension for Prisma. Ideally I'd like to add typings to a very generic interface (findMany, findUnique etc.) that all models' use, and then add my function to all models at runtime. But that's not how Prisma generate types.

0 Answers
Related