question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

No easy way to get prisma client table names in typescript

See original GitHub issue

Bug description

There is no typescript type containing a list of prisma client table names. Prisma.ModelName maps to the names in schema.prisma, which are Capitalized vs the camelCase used by prisma client, so they don’t work for typing with prisma client.

My use case is to create reusable validation logic, for example a validation checking case insensitive uniqueness. I want to be able to do it like this:

function checkExists(tableName: THE_MISSING_TYPE, fieldName: string, equals: string) {
  return prisma[tablename].findFirst({
   where: {
      [fieldName]: {
        equals,
        mode: 'insensitive',
      }
    }
  }
})

const exists = await checkExists('user', 'username', 'stan');

How to reproduce

In order to do get prisma client’s accepted table names in typescript, you need to do a workaround like this.

type FilterStartsWith<Set, Needle extends string> = Set extends `${Needle}${infer _X}` ? Set : never;
type FilteredKeys = FilterStartsWith<keyof PrismaClient, '$'>;

type TableName = keyof Omit<PrismaClient, FilteredKeys>;

function findManyDynamic(tableName: TableName) {
  return prismaClient[tableName].findMany?(...);
}

I basically filtered out keys that start with “$” from prisma client. Even when I do this, it still doesn’t work because every prisma client model is a separate type, rather than being unified under a generic PrismaModel type. I get the following error:

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

That’s a lot of hoops to jump through just to get a list of acceptable table names. Also, this means I will need to maintain the types myself and update it whenever prisma decides to change its internal structure in Prisma Client.

There’s also no type like PrismaClientModel available if I want to do it slightly differently like this.

function checkExists(table: THE_MISSING_TYPE, fieldName: string, equals: string) {
  return table.findFirst({
   where: {
      [fieldName]: {
        equals,
        mode: 'insensitive',
      }
    }
  }
})

const exists = await checkExists(prisma.user, 'username', 'stan');

Expected behavior

Prisma should provide a type containing table names accepted by prisma client, and a generic PrismaClientModel type that applies to all prisma client tables, with methods like findFirst, update etc.

Prisma information

Environment & setup

  • OS: 10.15.7
  • Database: Postgresql
  • Node.js version: v14.18.1

Prisma Version

Environment variables loaded from .env
prisma                  : 3.4.2
@prisma/client          : 3.4.2
Current platform        : darwin
Query Engine (Node-API) : libquery-engine 57771c0558568c7d08bd34c7248af5244ae16bd9 (at node_modules/@prisma/engines/libquery_engine-darwin.dylib.node)
Migration Engine        : migration-engine-cli 57771c0558568c7d08bd34c7248af5244ae16bd9 (at node_modules/@prisma/engines/migration-engine-darwin)
Introspection Engine    : introspection-core 57771c0558568c7d08bd34c7248af5244ae16bd9 (at node_modules/@prisma/engines/introspection-engine-darwin)
Format Binary           : prisma-fmt 57771c0558568c7d08bd34c7248af5244ae16bd9 (at node_modules/@prisma/engines/prisma-fmt-darwin)
Default Engines Hash    : 57771c0558568c7d08bd34c7248af5244ae16bd9
Studio                  : 0.438.0
Preview Features        : nativeTypes, interactiveTransactions

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:19
  • Comments:8

github_iconTop GitHub Comments

10reactions
captainkocommented, Feb 24, 2022

@jeremygottfried check this out

type IgnorePrismaBuiltins<S extends string> = string extends S
  ? string
  : S extends ''
  ? S
  : S extends `$${infer T}`
  ? never
  : S;

export type PrismaModelName = IgnorePrismaBuiltins<keyof PrismaClient>;
3reactions
neighbaacommented, Oct 13, 2022

I use type UncapitalizedModelName = Uncapitalize<Prisma.ModelName>;

Read more comments on GitHub >

github_iconTop Results From Across the Web

Names in the underlying database - Prisma
Mapping names in the Prisma schema allows you to influence the naming in your Client API without having to change the underlying database...
Read more >
TypeScript ORM for SQL Databases - Prisma
Prisma is a TypeScript ORM that makes you more confident with type safe database access. It's the easiest way to access SQL databases...
Read more >
Quickstart with TypeScript & SQLite - Prisma
In this Quickstart guide, you'll learn how to get started with Prisma from scratch using a plain TypeScript project and a local SQLite...
Read more >
Using Prisma Migrate | typescript-postgres
Create database tables with Prisma Migrate. ... 22 name String? ... If the prisma-client-js generator is defined in your schema, this will check...
Read more >
Using custom model and field names (Concepts) - Prisma
Learn how you can decouple the naming of Prisma models from database tables to improve the ergonomics of the generated Prisma Client API....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found