notiz-dev / nestjs-prisma-starter

Starter template for NestJS 😻 includes GraphQL with Prisma Client, Passport-JWT authentication, Swagger Api and Docker
MIT License
2.37k stars 336 forks source link

Incompatible types #454

Closed incompletude closed 2 years ago

incompletude commented 3 years ago

I'm using this example to build my own solution, but I stumbled into something that I'm not sure how to solve.

This is very much the same as the user.model.ts present in this example:

import { Field, ObjectType, registerEnumType } from "@nestjs/graphql"

export enum AccountStatus {
  Created = "Created",
  Verified = "Verified",
}

registerEnumType(AccountStatus, {
  name: "AccountStatus",
})

@ObjectType()
export class Account {
  @Field()
  public readonly slug: string

  @Field(() => AccountStatus)
  public status: AccountStatus
}

Then I have a service. In the return account I have a error message: Types of property 'status' are incompatible. because enums inside @prisma/client are defined as a const.

  public async create(input: AccountCreate): Promise<Account> {
    const account = await this.prismaService.account.create({
      data: {
        // whatever
      },
    })

    return account
  }

I can cast account to Account, but I prefer not to do that.

Rykuno commented 2 years ago

Try this registering the enum directly from the @prisma/client

import { registerEnumType, ObjectType, Field } from '@nestjs/graphql';
import { BaseModel } from '../../common/models/base.model';
import { User } from '../../user/user.model';
import { UserConnectionStatus } from '@prisma/client';

registerEnumType(UserConnectionStatus, {
  name: 'UserConnectionStatus',
});

@ObjectType()
export class UserConnection extends BaseModel {
  followerId: string;
  follower: User;
  followingId: string;
  following: User;
  @Field(() => UserConnectionStatus)
  status: UserConnectionStatus;
}
marcjulian commented 2 years ago

@Rykuno thats a perfect solution! But keep in mind that it exposes all specified values form your Prisma Schema of that enum via your GraphQL API.

Here is an example for the updated user.model.ts using @Rykuno's approach.

import {
  ObjectType,
  registerEnumType,
  HideField,
+  Field,
} from '@nestjs/graphql';
import { Post } from 'src/posts/models/post.model';
import { BaseModel } from 'src/common/models/base.model';
+import { Role } from '@prisma/client';

- export enum Role {
-  ADMIN = 'ADMIN',
-  USER = 'USER',
-}

registerEnumType(Role, {
  name: 'Role',
  description: 'User role',
});

@ObjectType()
export class User extends BaseModel {
  email: string;
  firstname?: string;
  lastname?: string;
+ @Field(() => Role)
  role: Role;
  posts: Post[];
  @HideField()
  password: string;
}