Skip to content
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

oneof enum generates incorrect code #2062

Open
v-morlock opened this issue Mar 12, 2024 · 11 comments · Fixed by hey-api/openapi-ts#46
Open

oneof enum generates incorrect code #2062

v-morlock opened this issue Mar 12, 2024 · 11 comments · Fixed by hey-api/openapi-ts#46
Assignees

Comments

@v-morlock
Copy link

Hi!

this model

      "VendingItemState": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "type"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "Pending"
                ]
              }
            }
          },
          {
            "type": "object",
            "required": [
              "type"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "Picked"
                ]
              }
            }
          },
          {
            "type": "object",
            "required": [
              "type"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "Placed"
                ]
              }
            }
          },
          {
            "type": "object",
            "required": [
              "content",
              "type"
            ],
            "properties": {
              "content": {
                "type": "string",
                "format": "date-time"
              },
              "type": {
                "type": "string",
                "enum": [
                  "Dispensed"
                ]
              }
            }
          },
          {
            "type": "object",
            "required": [
              "content",
              "type"
            ],
            "properties": {
              "content": {
                "type": "array",
                "items": [
                  {
                    "type": "string",
                    "format": "date-time"
                  },
                  {
                    "type": "string"
                  }
                ],
                "maxItems": 2,
                "minItems": 2
              },
              "type": {
                "type": "string",
                "enum": [
                  "Error"
                ]
              }
            }
          }
        ]
      },

generates the following code:

export type VendingItemState = ({
    type: VendingItemState.type;
} | {
    content: string;
    type: VendingItemState.type;
} | {
    content: Array<any>;
    type: VendingItemState.type;
});
export namespace VendingItemState {
    export enum type {
        PENDING = 'Pending',
    }
}

which is missing most of the options for "type"...

@mrlubos
Copy link
Collaborator

mrlubos commented Mar 12, 2024

@v-morlock hey, are you able to replicate the same issue in @nicolas-chaulet/openapi-typescript-codegen?

@v-morlock
Copy link
Author

Hi! Unfortunately yes

@mrlubos
Copy link
Collaborator

mrlubos commented Mar 12, 2024

@v-morlock uh, I see what's happening. What's the output you'd expect? Roll all those options into a single enum, or multiple enums per each option?

@v-morlock
Copy link
Author

Both would be fine to me - the value is representing a rust enum that looks like this:

#[derive(Serialize, Deserialize, Clone, schemars::JsonSchema, Eq, PartialEq, Debug)]
#[serde(tag = "type", content = "content")]
pub enum VendingItemState {
    Pending,
    Picked,
    Placed,
    Dispensed(chrono::DateTime<Utc>),
    Error(chrono::DateTime<Utc>, String),
}

so i think the direct mapping would be sth like below - one could make an argument that a separate enum isn't really necessary for enums with only a single value. But in practice, anything that gives the same end-result as the structure below would be fine to me. I don't think I'd ever really use the generated enum anyway. I think a single enum wouldn't work though because then it wouldn't be clear which options contain additional values and which don't.

export type VendingItemState = ({
    type: "Pending";
} | {
    type: "Picked";
} | {
    type: "Placed";
} | {
    type: "Dispensed;
    content: string;
} | {
    type: "Error";
    content: Array<any>;
});

@v-morlock
Copy link
Author

Btw, do you have an idea why the "content" array is typed as "any"?

@mrlubos
Copy link
Collaborator

mrlubos commented Mar 12, 2024

@v-morlock Got it, thanks! This is an interesting case, will have a look at it, but it will be available in the package I shared above as this one isn't really maintained

@mrlubos
Copy link
Collaborator

mrlubos commented Mar 13, 2024

@v-morlock please try with the latest version of @nicolas-chaulet/openapi-typescript-codegen 🎉

That should give you exactly what you need

export type ModelWithOneOfEnum = {
    foo: 'Bar';
} | {
    foo: 'Baz';
} | {
    foo: 'Qux';
} | {
    content: string;
    foo: 'Quux';
} | {
    content: [string | string];
    foo: 'Corge';
};

@mrlubos
Copy link
Collaborator

mrlubos commented Mar 15, 2024

@v-morlock I updated @nicolas-chaulet/openapi-typescript-codegen so it should now work out of the box. It is a huge change set, so I'd love if you could upgrade and let me know if anything breaks!

@mrlubos
Copy link
Collaborator

mrlubos commented Apr 11, 2024

@v-morlock how did you generate your OpenAPI specification?

@v-morlock
Copy link
Author

Hi! Thanks for developing that fix and sorry that I haven't found the time to test it yet. The spec is generated by the library "aide" for rust / axum

@mrlubos
Copy link
Collaborator

mrlubos commented Apr 11, 2024

@v-morlock for the minItems/maxItems array, would you be okay with output [Date | string, Date | string]?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants