Search code examples
typeormtypegraphql

How can I avoid code duplication with InputTypes in TypeGraphQL


I'm hoping to get some advice with setting up InputTypes in TypeGraphQL.

I am implementing many resolvers in a very generic way - I always have a createX and an updateX

Example with a "User" entity:

  @Mutation(returns => User)
  async createUser(@Arg('newUser') newUser: UserInput): Promise<User> {
    await this.mutatorValidation(newUser)
    return this.userRepository.save(newUser)
  }

  @Mutation(returns => User)
  async updateUser(
    @Arg('userId', type => String) userId: string,
    @Arg('updateUser') updateUser: Partial<UserInput> // <- THIS IS MY ISSUE
  ): Promise<User> {
    await this.mutatorValidation(updateUser)
    let userToUpdate = await this.user(userId)
    userToUpdate = { ...userToUpdate, ...updateUser }
    return this.userRepository.save(userToUpdate)
  }

User InputType:

import { Field, InputType, ID } from 'type-graphql'
import { IsEmail } from 'class-validator'
import { User } from '../../entity/User'

@InputType()
export class UserInput implements Partial<User> {

  @Field()
  @IsEmail()
  email: string;

  @Field()
  password: string;

  @Field()
  name: string;

  @Field({ nullable: true })
  jobTitle?: string;

  @Field({ nullable: true })
  isAdmin?: boolean;

  @Field(type => ID, { nullable: true })
  userGroupId?: string;

}

The issue is that when making an update call, all fields will be optional (we provide an ID, and then any number of fields we want to update). I am hoping there is a way to be able to reuse this InputType so that I can use it for both create and update? The obvious (lengthy) solution is to duplicate every InputType class and make all fields nullable but then there is a lot of code duplication and it would be easy to miss updating a field down the line. I tried applying the type Partial<UserInput> to the update arg but it complains that it is not an explicit type.

Is there a way to avoid the code duplication here? Many thanks in advance for any advice you can give!


Solution

  • It's planned but not yet possible.

    More info on GitHub issue: https://github.com/MichalLytek/type-graphql/issues/453