-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expose generic types for WhereInput
#6980
Comments
Note, for info: Prisma Client since |
That's good point! Thanks for letting me know |
I suggest to add something like this to generated types: export type Models = {
User: {
model: User;
where: UserWhereInput,
// other user related types
}
} What would make a lot of dynamic type generation cases much easier in future as well. So, I can represent type WhereInput<T extends Prisma.ModelName> = Prisma.Models[T]['where']; Link to related slack discussion: https://prisma.slack.com/archives/C021N1UPQ0Z/p1620644383003000 |
WhereInput
Hey @stalniy, since version function checkWhereInput<T>(model: T, input: Prisma.Args<T, 'findFirstOrThrow'>['where']) {
}
checkWhereInput(prisma.user, {
/* Auto-completion works */
}) And another variant on type-level only: type GetWherePayload<T extends Record<any, any>, M extends keyof any> =
Exclude<Prisma.Args<T[M], 'findFirstOrThrow'>['where'], undefined>
type test = GetWherePayload<typeof prisma, 'user'> Does that work for you? |
@millsp I have the following but as soon I have more than one model prisma starts complaining. type Models = Prisma.TypeMap["meta"]["modelProps"];
function checkWhereInput<T extends PrismaClient[Models]>(model: T, input: Prisma.Args<T, 'findFirstOrThrow'>['where']) {
model.findFirstOrThrow({where: input});
} |
@millsp Where are these new type utilities documented? |
@kdawgwilk We have some basic documentation over here |
@mateussilva92 This is a general limitation from TypeScript, not Prisma, here's the explanation. With your current code, you are trying to tell TS that you will potentially access any model in a typesafe manner. That seems sound and logic, but the type-system sees otherwise. While your union of models is type-safe, TS will say:
And that is true. Each model can have a There are ways to get over that though, byt they might not be efficient on the type-system or just not worth it. If your goal is to just have your function to be type-safe on the outside, and it does not matter so much on the inside implementation, I suggest you cast |
I want to share some information that I've gathered from previous comments. Hopefully, it will be helpful to someone. type Models = keyof typeof Prisma.ModelName;
type ArgsType<T extends Models> =
Prisma.TypeMap['model'][T]['operations']['findMany']['args'];
type WhereType<T extends Models> = NonNullable<ArgsType<T>['where']>;
type AndType<T extends Models> = NonNullable<WhereType<T>['AND']>; |
@joao-moonward Do you know which min version of prisma you need for that to work? |
@kdawgwilk I used |
@stalniy @joao-moonward @millsp I have a working solution to get model types by name created by inspecting the generated import { Prisma, PrismaClient } from '@prisma/client'
import PrismaRuntime from '@prisma/client/runtime/library'
import PrismaTypes = PrismaRuntime.Types
export { PrismaTypes }
export { Prisma, PrismaClient } from '@prisma/client'
export * as PrismaRuntime from '@prisma/client/runtime/library'
export type ModelName = Prisma.ModelName
export type PrismaModelName = ModelName
export const getPrismaModelProp = <N extends PrismaModelName>(name: N) =>
`${name.charAt(0).toLowerCase()}${name.slice(1)}` as PrismaModelProp<N>
export const getPrismaDelegate = <N extends PrismaModelName>(name: N, prisma: PrismaClient) =>
prisma[getPrismaModelProp(name)] as PrismaModelDelegate<N> as any // For generic model delegate
// Use `PrismaModel` for any available Prisma model (e.g. as a method parameter or generic type parameter)
// Use `PrismaModel<"YourModelName">` for specific Prisma model
export type PrismaModel<N extends ModelName = ModelName> = PrismaTypes.Result.DefaultSelection<PrismaModelPayload<N>>
export type PrismaModelProp<N extends ModelName = ModelName> = Uncapitalize<N>
export type PrismaModelType<N extends ModelName = ModelName> = Prisma.TypeMap['model'][N]
export type PrismaModelPayload<N extends ModelName = ModelName> = PrismaModelType<N>['payload']
export type PrismaModelDelegate<N extends ModelName = ModelName> = PrismaClient[PrismaModelProp<N>]
export type PrismaModels = { [N in Prisma.ModelName]: PrismaModel<N> }
export type PrismaModelProps = { [N in Prisma.ModelName]: PrismaModelProp<N> }
export type PrismaModelTypes = { [N in Prisma.ModelName]: PrismaModelType<N> }
export type PrismaModelPayloads = { [N in Prisma.ModelName]: PrismaModelPayload<N> }
export type PrismaModelDelegates = { [N in Prisma.ModelName]: PrismaModelDelegate<N> }
export type FindManyArgs<N extends ModelName> = PrismaModelType<N>['operations']['findMany']['args']
export type FindUniqueArgs<N extends ModelName> = PrismaModelType<N>['operations']['findUnique']['args']
export type WhereInput<N extends ModelName = ModelName> = NonNullable<FindManyArgs<N>['where']>
export type WhereAnd<N extends ModelName = ModelName> = NonNullable<WhereInput<N>['AND']>
export type WhereOr<N extends ModelName = ModelName> = NonNullable<WhereInput<N>['OR']>
export type WhereUniqueInput<N extends ModelName = ModelName> = NonNullable<FindUniqueArgs<N>['where']> |
Problem
I'm an author of https://casl.js.org/ and working on integration of prisma with that authorization library. The issue i have is inability to easily get
WhereInput
type for specific model in a generic way. I need this in order to properly type argument inside my function based on the argument. Primitive example:Suggested solution
Ideally, I'd like to have something like
Prisma.WhereInput<User>
orPrisma.WhereInput<'User'>
.Alternatives
There is quite hacky workaround that doesn't work if the client is not generated and requires TS 4.1+:
The text was updated successfully, but these errors were encountered: