openapi-typescript icon indicating copy to clipboard operation
openapi-typescript copied to clipboard

Array of response object in schema.yaml / schema.json does not result in array type in schema.d.ts

Open mklueh opened this issue 2 years ago • 4 comments

Description Array type of response object does not result in array type in schema

 "SomeResponseObject" : {
        "type" : "object",
        "properties" : {
          "page" : {
            "format" : "int64",
            "type" : "integer"
          },
          "pages" : {
            "format" : "int64",
            "type" : "integer"
          },
          "items" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/ResponseListItem"
            },
             "oneOf" : [ {
              "$ref" : "#/components/schemas/SomeItem"
            }, {
              "$ref" : "#/components/schemas/SomeOtherItem"
            } ]
          }
        }
      },

will result in

    SomeResponseObject: {
      /** Format: int64 */
      page?: number;
      /** Format: int64 */
      pages?: number;
      items?: components["schemas"]["SomeItem"] | components["schemas"]["SomeOtherItem"];
    };

Which does not represent the array but just a single item.

I've run Redocly and there are some issues, but nothing related to the object I'm referring to.

BTW the openapi.json / yaml is autogenerated by my Quarkus Application and this is the originating Java class:

@Data
@Builder
@AllArgsConstructor
public class SomeResponseObject {

    private long page;

    private long pages;

    @Schema(type = ARRAY, oneOf = {SomeItem.class, SomeOtherItem.class})
    private List<ResponseListItemDto> items;
}

I'm using

✨ openapi-typescript 6.7.0

Expected result

(in case it’s not obvious)

Checklist

mklueh avatar Nov 03 '23 07:11 mklueh

I think the oneOf on the array is throwing it off—since oneOf is mutually exclusive, it can’t easily coexist with other properties (or at least, it’s unclear how the original author intends for this to be resolved). Perhaps this is semantically valid but logically you really can only use oneOf on object-type Schema Objects.

Or if that property really is polymorphic, then I’d suggest moving the type: "array", items: … inside the oneOf so they don’t conflict.

drwpow avatar Nov 03 '23 10:11 drwpow

@drwpow thanks.

In my case the property is polymorphic. So this is basically not part of the specification?

Baeldung seems to confidently use it that way and this site is pretty reliable, which is wondering me now. https://www.baeldung.com/openapi-array-of-varying-types#1-oneof-keyword

Or if that property really is polymorphic, then I’d suggest moving the type: "array", items: … inside the oneOf so they don’t conflict.

Could you please show me how exactly that would look like in my schema? Not sure how it would project to the Java implementation.

Would I have to annotate the base class then with @Schema(type = ARRAY, oneOf = {SomeItem.class, SomeOtherItem.class})?

mklueh avatar Nov 03 '23 12:11 mklueh

Ah I got it backwards—it’s your items that are polymorphic and not the top-level property.

I’m not too familiar with that Java library you’re using, but you’ll need to have the oneOf on the items of the array, and not the array itself.

drwpow avatar Nov 03 '23 12:11 drwpow

So if we adjusted your original code, this is how it should look:

  "SomeResponseObject": {
    "type": "object",
      "properties": {
        "page": {
          "format": "int64",
          "type": "integer"
        },
        "pages": {
          "format": "int64",
          "type": "integer"
        },
        "items": {
          "type": "array",
          "items": {
-           "$ref": "#/components/schemas/ResponseListItem"
+           "oneOf": [
+             {"$ref": "#/components/schemas/ResponseListItem"},
+             {"$ref": "#/components/schemas/SomeItem"},
+             {"$ref": "#/components/schemas/SomeOtherItem"}
+           ]
          },
-         "oneOf": [
-           {"$ref": "#/components/schemas/SomeItem"},
-           {"$ref": "#/components/schemas/SomeOtherItem"}
-         ]
        }
      }
    }

drwpow avatar Nov 03 '23 12:11 drwpow

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.

github-actions[bot] avatar Aug 06 '24 12:08 github-actions[bot]

This issue was closed because it has been inactive for 7 days since being marked as stale. Please open a new issue if you believe you are encountering a related problem.

github-actions[bot] avatar Aug 14 '24 02:08 github-actions[bot]