prisma1 icon indicating copy to clipboard operation
prisma1 copied to clipboard

Prisma client - generate enum types

Open maxprilutskiy opened this issue 7 years ago • 9 comments

Is your feature request related to a problem? Please describe. Prisma client should take advantage of TypeScript's enums instead of just using type

Describe the solution you'd like I would like to make codegen module generate TypeScript enums from GraphQL's enums, instead of types.

Advantages:

  1. More obvious;
  2. Utilizes TypeScript language features;
  3. Improves compatibility with other libraries related to code generation.

maxprilutskiy avatar Nov 06 '18 16:11 maxprilutskiy

I am going to submit a PR with this change

maxprilutskiy avatar Nov 06 '18 16:11 maxprilutskiy

PR: #3438

maxprilutskiy avatar Nov 07 '18 17:11 maxprilutskiy

Thanks a lot for opening this issue and suggesting this change. This is a little bit tricky since the enum TS syntax and the currently supported string literal syntax are not compatible (this is by design - see this Github issue).

Your proposed change would result in a breaking change which would in most cases require a more explicit syntax. Consider the following example based on the giving datamodel.prisma snippet:

Datamodel:

enum Color { Red, Blue }

Resulting TS client types using literal string syntax (current implementation):

type Color = 'Red' | 'Blue'

// allows for the following
const c1 = 'Red' // ok
const c2 = 'Green' // compile error

Resulting TS client types using enum syntax (your suggestion):

enum Color {
  Red: 'Red',
  Blue: 'Blue'
}

// allows for the following
const c1 = 'Red' // compile error
const c2 = 'Green' // compile error
const c3 = Color.Red // ok

There is however a workaround described in the comments of the mentioned issue which would allow both the 'Red' and the Color.Red syntax. See the following:

export type Color = 'Red' | 'Blue'
export const Color: {
  Red: 'Red',
  Blue: 'Blue',
} = {
  Red: 'Red',
  Blue: 'Blue',
}

// allows for the following
const c1 = 'Red' // ok
const c2 = 'Green' // compile error
const c3 = Color.Red // ok

While my suggested workaround wouldn't use the canonical enum syntax you've described, it would still allow for both referencing syntaxes. Does this solve your requirements?

schickling avatar Nov 13 '18 09:11 schickling

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 10 days if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Jan 08 '19 23:01 stale[bot]

Any progress on this? The difference in the way Prisma generates the enum (string unions) versus my GraphQL client's way (typescript enum) causes conflicts in the types.

VRspace4 avatar Jan 14 '19 19:01 VRspace4

I would like to throw weight behind switching to canonical enum syntax here. I personally only see the explicitness as a positive especially since enum values should ideally be seen as opaque. This change would also help the generated types follow a favourite POLA! :)

chrisui avatar Feb 11 '19 19:02 chrisui

Any progress on this? The difference in the way Prisma generates the enum (string unions) versus my GraphQL client's way (typescript enum) causes conflicts in the types.

I fixed the incompatibility between GraphQL Code Generator enums and prisma client enums by setting enumAsTypes:true in codegen.yml. See here for more details.

WaqasAliAbbasi avatar Feb 28 '20 10:02 WaqasAliAbbasi

Why is this not getting more attention? The point of declaring an enum is to... have an enum

sarink avatar Jan 17 '22 03:01 sarink

I'm in favor of enum.

I meet a problem in this way.

export type Color = 'Red' | 'Blue'
export const Color: {
  Red: 'Red',
  Blue: 'Blue',
} = {
  Red: 'Red',
  Blue: 'Blue',
}

My project is base on nextjs. I import Color in a function, and the function is used in react component.Then there comes webpack error.

Because the frontend code is importing prisma generated js file.

If the enum is just typescript enum. It won't happend.

export enum Color: {
  Red = 'Red',
  Blue = 'Blue',
}

I don't want write it as a string. because auto generated enum is easier for maintenance.

While I don't care about what the enum's actual value is.

model Buff {
  id   String @id @default(cuid())
  name String
}

enum NAME{
  AAA
  BBB
}

export interface IBuff extends PartialOmitAnyId<Buff> {
}

const data = {
 name: NAME.AAA
}

If I care about the actual value. I will use String as type.

model Buff {
  id   String @id @default(cuid())
  name String
}

export interface IBuff extends PartialOmitAnyId<Buff> {
 name: "aaaa"|"bbbb"
}

cqh963852 avatar Jun 14 '22 17:06 cqh963852