Hi Im tryng to build a DAO class using prisma aplyng SOLID principles. The idea is to build generic functions and an abstract class so i can aply them on the diferen modules by dependence injection. So for example when i need to build my Users.Service.ts Ill extend GenericClass and inyect the funcions i need for thar module create, update and so on. But im having probems with typescript. At the botom is the entire code for the Generic service. The error I get from typescript is :
This expression is not callable. Each member of the union type '((args: SelectSubset<T, UsersCreateArgs>) => Prisma__UsersClient<UsersGetPayload, never>) | ((args: SelectSubset<...>) => Prisma__ProductsClient<...>) | ((args: SelectSubset<...>) => Prisma__CartsClient<...>)' has signatures, but none of those signatures are compatible with each other
What i understund of it is that typescript can be certain about PrismaClient[T]
being of the same kind that dto:GenericDto<T>
I ve builded some validations for it but, doesnt seem to work. Probably there are a simpler solution for it, but i dont see it . The abstract class is not yet implemented because im having problems with the firs function. and the function is outside the class so i can customize my classes depending on the need.
This is the only implementation that works, but it sucks on scalability Does someone knows how to do this the right way? Thanks so much
import { Prisma, PrismaClient } from '@prisma/client'
export interface IParam<T extends Lowercase<Prisma.ModelName>> {
client: PrismaClient[T]
data: Dto<T>
model: T
}
type Dto<T extends Lowercase<Prisma.ModelName>> = PrismaClient[T] extends { create: (args: { data: infer U }) => Promise<unknown> } ? U : never
type Models<T extends keyof PrismaClient> =
PrismaClient[T] extends { create: infer U }
? { create: U }
: never
type createMethodType<T extends Lowercase<Prisma.ModelName>> = (dto: Dto<T>, client: Models<T>) => Promise<unknown>
class CreatorObject {
constructor (
public carts = async (dto: Dto<'carts'>, client: Models<'carts'>): Promise<any> => {
return await client.create({ data: dto })
},
public users = async (dto: Dto<'users'>, client: Models<'users'>): Promise<any> => {
return await client.create({ data: dto })
},
public products = async (dto: Dto<'products'>, client: Models<'products'>): Promise<any> => {
return await client.create({ data: dto })
}
) {}
}
export const clousure = (model: keyof CreatorObject): any => {
const creatorObject = new CreatorObject()
const create: createMethodType<typeof model> = async (dto, client) => {
const response = creatorObject[model]
return response
}
return { create }
}