MichalLytek / typegraphql-prisma

Prisma generator to emit TypeGraphQL types and CRUD resolvers from your Prisma schema
https://prisma.typegraphql.com
MIT License
887 stars 113 forks source link

TypeScript error in overloading UserResolver's deleteManyUser mutation #421

Closed suiramdev closed 1 year ago

suiramdev commented 1 year ago

Describe the Bug So it was several months before I got my hands on my code again, and since I'd learned a lot, I decided to start from scratch. It turns out that, when I try to replace the behavior of one of the generated CRUDs (which was originally working ?), in this case deleteMany and deleteOne, I get an error with typescript :

import { Resolver, Mutation, Ctx, Info, Args } from "type-graphql";
import {
    User,
    UserCrudResolver,
    type DeleteManyUserArgs,
    type DeleteOneUserArgs,
    AffectedRowsOutput,
} from "@generated/type-graphql";
import { GraphQLResolveInfo } from "graphql";
import { Context } from "@/context";

@Resolver(() => User)
export class UserResolver extends UserCrudResolver {
    @Mutation(() => AffectedRowsOutput)
    async deleteManyUser(@Ctx() ctx: Context, @Info() info: GraphQLResolveInfo, @Args() args: DeleteManyUserArgs): Promise<AffectedRowsOutput> {
        return ctx.prisma.user.deleteMany({ ...args, where: { ...args.where, persistent: false }});
    }

    @Mutation(() => User)
    async deleteOneUser(@Ctx() ctx: Context, @Info() info: GraphQLResolveInfo, @Args() args: DeleteOneUserArgs): Promise<User | null> {
        const user = await ctx.prisma.user.findUnique({ ...args });
        if (!user || user.persistent) return null;

        return ctx.prisma.user.delete({ ...args });
    }
}
/Users/suiramdev/Projects/storedge/core/node_modules/.pnpm/type-graphql@2.0.0-beta.3_class-validator@0.14.0_graphql-scalars@1.22.2_graphql@16.8.1/node_modules/type-graphql/build/cjs/helpers/findType.js:25
        throw new errors_1.NoExplicitTypeError(prototype.constructor.name, propertyKey, parameterIndex, argName);
              ^
NoExplicitTypeError: Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for parameter #2 of 'deleteManyUser' of 'UserResolver' class.
    at findType (/Users/suiramdev/Projects/storedge/core/node_modules/.pnpm/type-graphql@2.0.0-beta.3_class-validator@0.14.0_graphql-scalars@1.22.2_graphql@16.8.1/node_modules/type-graphql/build/cjs/helpers/findType.js:25:15)
    at getParamInfo (/Users/suiramdev/Projects/storedge/core/node_modules/.pnpm/type-graphql@2.0.0-beta.3_class-validator@0.14.0_graphql-scalars@1.22.2_graphql@16.8.1/node_modules/type-graphql/build/cjs/helpers/params.js:10:62)
    at /Users/suiramdev/Projects/storedge/core/node_modules/.pnpm/type-graphql@2.0.0-beta.3_class-validator@0.14.0_graphql-scalars@1.22.2_graphql@16.8.1/node_modules/type-graphql/build/cjs/decorators/Args.js:12:42
    at /Users/suiramdev/Projects/storedge/core/src/schema/resolvers/user.ts:12:37
    at DecorateProperty (/Users/suiramdev/Projects/storedge/core/node_modules/.pnpm/reflect-metadata@0.1.13/node_modules/reflect-metadata/Reflect.js:553:33)
    at Reflect.decorate (/Users/suiramdev/Projects/storedge/core/node_modules/.pnpm/reflect-metadata@0.1.13/node_modules/reflect-metadata/Reflect.js:123:24)
    at __decorate (/Users/suiramdev/Projects/storedge/core/src/schema/resolvers/user.ts:4:92)
    at Object.<anonymous> (/Users/suiramdev/Projects/storedge/core/src/schema/resolvers/user.ts:15:11)
    at Module._compile (node:internal/modules/cjs/loader:1241:14)
    at Module.m._compile (/Users/suiramdev/Projects/storedge/core/node_modules/.pnpm/ts-node@10.9.1_@types+node@20.8.2_typescript@5.2.2/node_modules/ts-node/src/index.ts:1618:23)

I can't figure out why, I've tried a bunch of things, and it sometimes warns me of the same thing on the @Ctx() field.

MichalLytek commented 1 year ago

It can't be a import type DeleteManyUserArgs as it's erased during compilation and TypeGraphQL has no type reflection available for @Args() args: DeleteManyUserArgs

suiramdev commented 1 year ago

Oh. Sorry for taking up your time. In fact, that was the cause of the problem, now I get it. For anyone who cares, here is what my resolver looks like, so :

import { Resolver, Mutation, Ctx, Arg } from "type-graphql";
import {
    User,
    UserWhereInput,
    UserWhereUniqueInput,
    AffectedRowsOutput,
} from "@generated/type-graphql";
import { GraphQLError } from "graphql";
import { Context } from "@/context";

@Resolver(() => User)
export class UserResolver {
    @Mutation(() => AffectedRowsOutput)
    async deleteManyUser(@Ctx() ctx: Context, @Arg("where") where: UserWhereInput): Promise<AffectedRowsOutput> {
        return ctx.prisma.user.deleteMany({ where: { ...where, persistent: false }});
    }

    @Mutation(() => User, { nullable: true })
    async deleteOneUser(@Ctx() ctx: Context, @Arg("where") where: UserWhereUniqueInput): Promise<User | null> {
        const user = await ctx.prisma.user.findUnique({ where });
        if (!user) return null;
        if (user.persistent) throw new GraphQLError("Cannot delete a persistent user");

        return ctx.prisma.user.delete({ where });
    }
}