Skip to content

[BUG][typescript-angular] Angular service doesn't convert uniqueItems to set #14055

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

Open
5 of 6 tasks
jdgarvey opened this issue Nov 17, 2022 · 3 comments
Open
5 of 6 tasks

Comments

@jdgarvey
Copy link

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

Running into a typing issue when using uniqueItems and an Angular service.
When I have a schema that contains an array property with uniqueItems set to true, the generated typescript model is typed to a Set.

Schema

TestDto:
  required:
    - a
  type: object
  properties:
    a:
      uniqueItems: true
      type: array
      items:
        type: string

Generated Model

export interface TestDto { 
    a: Set<string>;
}

However, the corresponding generated Angular service does not do anything to convert the array that comes back from the API to a Set, so the result is a value that is typed to a set but actually contains an array. This breaks any consuming code that is using the correct type.

Return from the Angular Service

return this.httpClient.request<TestDto>('get', `${this.configuration.basePath}${localVarPath}`,
    {
        context: localVarHttpContext,
        responseType: <any>responseType_,
        withCredentials: this.configuration.withCredentials,
        headers: localVarHeaders,
        observe: observe,
        reportProgress: reportProgress
    }
);

Example where this would break

import { TestDto } from "./output";

const jsonApiResponse = {a: ['foo', 'bar']};
const receivingVariable: TestDto = jsonApiResponse;
// Results in error:
// Type '{ a: string[]; }' is not assignable to type 'TestDto'.
//  Types of property 'a' are incompatible.
//    Type 'string[]' is missing the following properties from type 'Set<string>': add, clear, delete, has, and 2 more.

We are currently converting the response to unknown and then to our own model to get around this issue.

openapi-generator version

6.2.1

OpenAPI declaration file content or url

https://github.com/jdgarvey/openapi-unique-items-bug/blob/main/spec.yml

Generation Details

npx openapi-generator-cli generate -g typescript-angular -i spec.yml -o output

Steps to reproduce

Reproduction repository: https://github.com/jdgarvey/openapi-unique-items-bug
You can view the spec there, then run npx openapi-generator-cli generate -g typescript-angular -i spec.yml -o output to update output if you want.

Related issues/PRs

#11746

Suggest a fix

As far as I can tell, we would need to recursively traverse the httpClient response JSON and somehow convert arrays to sets if that corresponding property has uniqueItems: true.

@skatterwe
Copy link

skatterwe commented Dec 8, 2022

This bug also occurs in request payloads. If the swagger specification includes an array with unique items as request payload, it is passed as an empty object instead of the array that is expected.

...
"requestBody": {
          "description": "...",
          "content": {
            "application/json": {
              "schema": {
                "uniqueItems": true,
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            }
          }
        },
...

Results into the following Model:

export interface RequestParams {
  xApiVersion: string;
  requestBody?: Set<string>;
}

Which is fine, but the payload that is send is an empty object. Maybe due to the fact that JSON.stringify(new Set([1])) returns '{}'?

@akleemans
Copy link

We also encounter this issue. As we don't want to use hacky casts like ['a', 'b'] as unknown as Set<string>, we decided to drop the uniqueItems-property.

It would be nice if there was one of these options:

  1. Properly support Sets and convert them to (unique) arrays before sending them as JSON.
  2. Add an option to the generator to represent the OpenAPI-array with uniqueItems as a TypeScript Array.

@ZielMartin
Copy link

ZielMartin commented Jan 21, 2025

I'm affected by this as well.
For now you can use the type-mapping property of the generator to use Array in place of Set:
for cli add --type-mappings=set=Array
for build.gradle add
typeMappings = [
set: 'Array'
]
(I dont understand how to do multiline code blocks :) )

full disclosure, I got the workaround from stackoverflow:
https://stackoverflow.com/a/73280040

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

No branches or pull requests

4 participants