#How can I preserve precise Prisma typings when abstracting the client away in a NestJS service?

4 messages · Page 1 of 1 (latest)

lethal kestrel
#

I'm building an application with NestJS, and I've decided to adopt a service-oriented approach instead of using the Prisma client directly in other services. So, I'm extracting my database operations into separate methods within a service. Here's an example:


async findLimit(findLimitInput: FindLimitInput): Promise<Limit | null> {
  const { where, select, include } = findLimitInput;

  return this.prisma.limit.findUnique({
    where: {
      ...SOFT_DELETE_CONDITION,
      ...where,
    },
    ...addSelectOrIncludeOption({ select, include }),
  });
}

This method returns the Limit type, which is generated by Prisma. The problem I run into is when I use the select or include statements. In these cases, the method would still return the Limit type, even though the actual returned object could be a subset or superset of the Limit model.

My question is, is there a way to maintain the same precision of typing that you get when using the client directly, but within my service-oriented NestJS architecture? Specifically I would like the returned type to reflect the actual fields selected or included in my query.

summer bridge
#

Hey @lethal kestrel

To maintain precise Prisma typings when abstracting the client in nestjs, use generics. For example, you can define a generic type T that extends Prisma.LimitFindUniqueArgs and return Prisma.LimitGetPayload<T> | null. This way, the returned type dynamically reflects the actual fields selected or included in your query

lethal kestrel
# summer bridge Hey <@732737923706781777> To maintain precise Prisma typings when abstracting ...

I got so happy when I saw your response, but when I tried it, it doesn't seem to work

async findLimit<T extends Prisma.LimitFindUniqueArgs>(findLimitInput: T): Promise<Prisma.LimitGetPayload<T> | null> {
        return this.prisma.limit.findUnique(findLimitInput);
    }

it gives error

Type '{ id: string; createdAt: Date; updatedAt: Date; deletedAt: Date | null; type: LimitType; duration: LimitDuration; amount: number; } | null' is not assignable to type 'GetFindResult<$LimitPayload<DefaultArgs>, T> | null'.
  Type '{ id: string; createdAt: Date; updatedAt: Date; deletedAt: Date | null; type: LimitType; duration: LimitDuration; amount: number; }' is not assignable to type 'GetFindResult<$LimitPayload<DefaultArgs>, T>'.ts(2322

maybe i am using the wrong version of prisma?

lethal kestrel
#

@summer bridge Oh wow the AI helped me out.

    async findLimit<T extends Prisma.LimitFindUniqueArgs>(
        args: Prisma.SelectSubset<T, Prisma.LimitFindUniqueArgs>,
    ): Promise<Prisma.LimitGetPayload<T> | null> {
        return this.prisma.limit.findUnique(args);
    }

This does the job. thank you so much @summer bridge you legitimately will save me dosens of hours