-
-
Notifications
You must be signed in to change notification settings - Fork 507
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature request] Generate Enums AND Union types #941
Comments
I think this could be offered as an option. I feel strongly that the default behavior of string unions shouldn’t change, because when data’s coming from an object it’s much easier to coerce a string union than a TypeScript enum. One question I’d like to ask is: how would you envision this working? Like, what would the import path be? The following would have to be considered:
Adding a proposal that takes into account those things would really help implementing (asking for anyone reading this thread!) |
Absolutely agree on this 💯 . I also always go with string unions instead of enums. I wouldn't go with an option, but instead as you mentioned default behaviour of string unions shouldn't change, lets just add enums/object exported along with it. If we check how Prisma does it: model User {
id String @id @default(uuid())
email String @unique
role Role @default(STANDARD)
}
enum Role {
STANDARD
APPRENTICE
SUPERVISOR
ADMINISTRATOR
} Prisma CLI is going to generate types as: export const Role: {
STANDARD: 'STANDARD',
APPRENTICE: 'APPRENTICE',
SUPERVISOR: 'SUPERVISOR',
ADMINISTRATOR: 'ADMINISTRATOR'
};
export type Role = (typeof Role)[keyof typeof Role] And frontend can consume it as: import { Role } from '@prisma/client';
type MyRoleType = Role; // MyRoleType is of type string union "APPRENTICE" | "STANDARD" | "SUPERVISOR" | "ADMINISTRATOR"
const myRole = Role.ADMINISTRATOR; // myRole value is "ADMINISTRATOR" In our case of generating types from OpenAPI, I would maybe go with more explicit version, where beside generated string union |
Rather than generating an enum, how about generating a concrete array of strings, and then generating the string union from that? export const RoleStrings = [
'STANDARD',
'APPRENTICE',
'SUPERVISOR',
'ADMINISTRATOR',
] as const;
export type Roles = typeof RoleStrings[number]; This way we don't have to worry about the weird behavior of |
Also works, just accessing of the values becomes bit less idiomatic imo, |
Maybe approach form similar library will be helpful to implement this feature. |
This is a very attractive feature for the same reasons that @mkosir outlined above. My use case would be that I've form controls in the UI where the values are dictated by an API and it's documentation. Right now i'm having to manually keep those choices in sync, but an enum would give me more flexibility to reference things. I'd definitely agree that any enums generated should be "extras" and not override string unions 👍 |
We've moved to serializing the Doing so allows us to access the literal enum values, rather than just the types + unions, which is very useful both for getting access to schema union types, and for reflecting parts of the schema back to clients at run-time. We started out using JSON module imports, but the the types from such imports are looser than we would like. import mySchema1 from 'schema.json';
const mySchema2 = {
components: {
schemas: {
Status: {
type: 'string',
enum: ['initial', 'processing', 'complete']
}
}
} as const;
mySchema1.components.schemas.Status.enum; // string[]
mySchema2.components.schemas.Status.enum; // ['initial', 'processing', 'complete'] See this comment for more details. |
I wrote this: https://github.com/openapi-typescript-infra/openapi-typescript-enum which will add enums. I don't like the way I had to write it - in that wrapping the CLI with a custom transform involves copying the CLI. Would be nice to have transform/postTransform be a CLI arg that points to some node-resolvable code. |
So I’ve already started planning some big changes to v7 (#1344) and I think that would make the enum work significantly easier. The major blocker with enums is unlike unions they can’t be dynamically inlined in an interface. So that means hoisting out every But if people aren’t opposed to some minor breaking changes, if we can lean on This will get shipped either way, but between deep param scanning, discriminators, operations, and now enums, there are a lot of individual, overlapping efforts of “collect all the things, generate code, then reference everything properly” which Redocly could simplify greatly. |
I'd definitely vote for centralizing on @redocly/openapi-core. I don't know how the community is or how the code is, but centralization in interpretation of openapi specs is undoubtedly a good thing given the intricacy of the spec and the changes that are likely to come along... |
Forgot to update this issue: the 7.x is still in testing and in the final bug-bashing phase, but is usable for most schemas today and will get a release candidate soon! And ICYMI it does rely on the Redocly CLI underneath for schema validation and parsing (which is lightweight and doesn’t introduce any bloat to the project). |
Huzzah! Looking forward to adopting 7.x. We used redocly for our tooling too, so I'm glad to have picked the same. We're able to really slice and dice the specs this way. Now if only I could replace the Java codegen with something less horrific. |
@drwpow current In most cases I get such result:
Here is my scheme
Tried with openapi-typescript@7.0.0-next.5 |
It's nice that v7 has tne enum flag, but I'd love to see this issue resolved (generating both) |
This issue is stale because it has been open for 90 days with no activity. If there is no activity in the next 7 days, the issue will be closed. |
Having this would make |
Hey 👋
I think it would be great if we could generate Enum types and Union types all together (or at least as enum types). Basically same thing as Prisma does when generating types for database models 🚀
Wdyt?
The text was updated successfully, but these errors were encountered: