MichalLytek / type-graphql

Create GraphQL schema and resolvers with TypeScript, using classes and decorators!
https://typegraphql.com
MIT License
8.03k stars 676 forks source link

ObjectType decorator reads TypeORM @BeforeInsert() decorator as Field with Nestjs app #375

Closed rkawajan closed 5 years ago

rkawajan commented 5 years ago

Nestjs app runs fine but I get problem message on VSCode & Console.

user.entity.ts

import {
  Entity,
  ObjectIdColumn,
  ObjectID,
  Column,
  Index,
  CreateDateColumn,
  UpdateDateColumn,
  BeforeInsert,
} from 'typeorm';
import { ObjectType, Field, ID } from 'type-graphql';
import * as admin from 'firebase-admin';

@Entity('users')
@ObjectType()
export class User {
  @Field(type => ID)
  @ObjectIdColumn()
  id?: ObjectID;

  @Field({ nullable: true })
  @Index('FIREBASE_UID', { unique: true, sparse: true })
  @Column({ nullable: true })
  firebase_uid?: string;

  ...

  @Field({ nullable: true })
  @CreateDateColumn({ type: 'timestamp', nullable: true })
  created_at?: Date;

  @Field({ nullable: true })
  @UpdateDateColumn({ type: 'timestamp', nullable: true })
  updated_at?: Date;

  @BeforeInsert()
  async createFirebaseUser(): Promise<void> {
    return await admin
      .auth()
      .createUser({
        phoneNumber: this.phone,
      })
      .then((user)=> {
        this.firebase_uid = user.uid;
      });
  }
}

user.resolver.ts

import { Resolver, Query, Mutation, Args } from '@nestjs/graphql';
import { UserService } from './user.service';
import { User } from './user.entity';
import { UserCreateInput } from './dto/user-create.input';

@Resolver(of => User)
export class UserResolver {
  constructor(private readonly userService: UserService) {}

  @Query(returns => [User])
  async users(): Promise<User[]> {
    return await this.userService.findAll();
  }

  @Mutation(returns => User)
  async createUser(@Args('data') data: UserCreateInput): Promise<User> {
    const user = await this.userService.create(data);
    return user;
  }
}

Logs src/user/user.resolver.ts(17,48): error TS2345: Argument of type 'UserCreateInput' is not assignable to parameter of type 'User'. [1] Property 'createFirebaseUser' is missing in type 'UserCreateInput' but required in type 'User'.

Enviorment:

MichalLytek commented 5 years ago

It's not

@ObjectType decorator reads TypeORM @BeforeInsert() decorator as Field

But

TypeScript requires the passed object (UserCreateInput) to have defined a method createUser that is defined in User class

Your UserService should take UserCreateInput as an argument, not a User Entity.

You can also use the Subscriber class for that: https://github.com/typeorm/typeorm/blob/master/docs/listeners-and-subscribers.md#what-is-a-subscriber

MichalLytek commented 5 years ago

Closing for a housekeeping purposes 🔒