Error when using Prisma with tRPC: Return type of exported function has or is using name 'prisma' from external module

Viewed 149

I'm trying to integrate Prisma with tRPC for my backend. Both of them alone work fine but once I try to integrate them with each other an error is thrown.

This is the error message I get:

TS4058: Return type of exported function has or is using name 'prisma' from external module "/Users/nils/Code/nextjs-coespace/node_modules/.prisma/client/index" but cannot be named

The file I get my Prisma client from:

// Note! This file has been copied from:
// https://github.com/prisma/prisma-examples/blob/latest/typescript/rest-nextjs-api-routes-auth/lib/prisma.ts

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

// PrismaClient is attached to the `global` object in development to prevent
// exhausting your database connection limit.
//
// Learn more:
// https://pris.ly/d/help/next-js-best-practices

// eslint-disable-next-line import/no-mutable-exports
let prisma: PrismaClient;

if (process.env.NODE_ENV === 'production') {
  prisma = new PrismaClient();
} else {
  if (!global.prisma) {
    global.prisma = new PrismaClient();
  }
  prisma = global.prisma;
}

export default prisma;

My tRPC controller:

import createRouter from '@/src/lib/server/trpc/routers/router';
import prisma from '@/src/lib/server/prisma';
import { z } from 'zod';

export default function locationRouter() {
  return createRouter()
    .mutation('create', {
      input: z.object({
        id: z.string().uuid(),
        // ...
      }),
      resolve(req) {
        return prisma.location.create({
          data: req.input,
        });
      },
    })
    .query('findMany', {
      resolve() {
          return prisma.location.findMany()
      },
    });
}
2 Answers

I think it's similar to this

I had a similar problem, which I solved by displaying the statement

You're returning a promise that encapsulates prisma from your resolve, which means prisma is part of the return type, leading to the error message. The error message makes sense if you think about it.

The solution is to await the result explicitly, which leads to prisma not being in the resolve. You're still returning a promise of course, but that await prevents prisma from being exported with the export type LocationRouter = typeof locationRouter. If you hover on resolve, you'll see the signature is

(property) resolve: ProcedureResolver<unknown, undefined, trpc.InferLast<Promise<template[]> & {
    [prisma]: true;
}>>

The following fixes my error (and possibly yours):

  .query("findMany", {
    resolve: async () => {
      return await prisma.location.findMany()
    },
  })

With the await, the signature of resolve is now

(property) resolve: ProcedureResolver<unknown, undefined, template[]>

You will need to do this for every resolve that uses prisma.

Related