No easy way to get prisma client table names in typescript
See original GitHub issueBug 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:
- Created 2 years ago
- Reactions:19
- Comments:8
Top GitHub Comments
@jeremygottfried check this out
I use
type UncapitalizedModelName = Uncapitalize<Prisma.ModelName>;