Skip to content

Support for Dictionaries, HashMaps and Associative Arrays #92

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

Closed
Saegrov opened this issue Nov 18, 2019 · 4 comments · Fixed by #130
Closed

Support for Dictionaries, HashMaps and Associative Arrays #92

Saegrov opened this issue Nov 18, 2019 · 4 comments · Fixed by #130

Comments

@Saegrov
Copy link

Saegrov commented Nov 18, 2019

Swagger has support for describing the types for HashMaps but currently swagger-to-ts only types these as object.

Swaggerdocs on this: https://swagger.io/docs/specification/data-models/dictionaries/

Example

Given this json:

{
  "swagger": "2.0",
  "info": {
    "description": "Api Documentation",
    "version": "1.0",
    "title": "Api Documentation",
    "termsOfService": "urn:tos",
    "contact": {},
    "license": {
      "name": "Apache 2.0",
      "url": "http://www.apache.org/licenses/LICENSE-2.0"
    }
  },
  "host": "localhost:8080",
  "basePath": "/",
  "definitions": {
    "CamundaFormField": {
      "type": "object",
      "required": ["displayType", "id", "label", "options", "responseType"],
      "properties": {
        "displayType": {
          "type": "string",
          "enum": ["radio", "date", "select", "textfield", "unknown"]
        },
        "id": { "type": "string" },
        "label": { "type": "string" },
        "options": {
          "type": "object",
          "additionalProperties": { "type": "string" }
        },
        "responseType": {
          "type": "string",
          "enum": [
            "booleanField",
            "stringField",
            "longField",
            "enumField",
            "dateField",
            "customTypeField",
            "unknownFieldType"
          ]
        },
        "value": { "type": "string" }
      },
      "title": "CamundaFormField"
    }
  }
}

Created from this Java class

@ApiModel("CamundaFormField")
public class CamundaFormFieldDto {

    @ApiModelProperty(required = true)
    private String id;

    @ApiModelProperty(required = true)
    private CamundaFormFieldTypeEnum responseType;

    @ApiModelProperty(required = true)
    private String label;

    @ApiModelProperty(required = true)
    private CamundaFormFieldDisplayTypeEnum displayType;

    @ApiModelProperty(required = true)
    private Map<String, String> options;

    private String value;
     /* ... more */ 
}

I get this result where the option property gets typed as object

export interface CamundaFormField {
  displayType: 'radio' | 'date' | 'select' | 'textfield' | 'unknown';
  id: string;
  label: string;
  options: object
  responseType:
    | 'booleanField'
    | 'stringField'
    | 'longField'
    | 'enumField'
    | 'dateField'
    | 'customTypeField'
    | 'unknownFieldType';
  value?: string;
}

The result I wanted in this case was:

export interface CamundaFormField {
  displayType: 'radio' | 'date' | 'select' | 'textfield' | 'unknown';
  id: string;
  label: string;
  options: Record<string, string>
  responseType:
    | 'booleanField'
    | 'stringField'
    | 'longField'
    | 'enumField'
    | 'dateField'
    | 'customTypeField'
    | 'unknownFieldType';
  value?: string;
}

Or if you want to support Typescript lower than 2.1:

export interface CamundaFormField {
  displayType: 'radio' | 'date' | 'select' | 'textfield' | 'unknown';
  id: string;
  label: string;
  options: {[key:string]: string}
  responseType:
    | 'booleanField'
    | 'stringField'
    | 'longField'
    | 'enumField'
    | 'dateField'
    | 'customTypeField'
    | 'unknownFieldType';
  value?: string;
}

I'm happy to provide a PR if you want. Great library!

@drwpow
Copy link
Contributor

drwpow commented Jan 2, 2020

Great library!

🤗

I'm happy to provide a PR if you want

While a PR would be greatly appreciated, it would be pretty sizable in scale because this is part of the version 3 spec which isn’t currently supported (though it’s probably high time this library added that support). I think this library probably needs a rewrite to be a bit more maintainable (I wrote it before becoming more comfortable with lexers, which I’d like to use moving forward, but, hey, everyone’s gotta start somewhere! Even Babel’s first version was sebmck’s first crack at it).

What I’ll do is open an issue to support Swagger v3 specs, and close this one, if that’s all right. Hopefully this will be taken care of by that.

@drwpow drwpow closed this as completed Jan 2, 2020
@drwpow drwpow mentioned this issue Feb 2, 2020
@drwpow
Copy link
Contributor

drwpow commented Feb 2, 2020

@Saegrov I apologize—this isn’t unique to v3 at all! This was actually a bug. This library did support additionalProperties at the top-level, but it accidentally didn’t respect it for nested properties. That will be fixed in #130, and I’ll push a version to npm as soon as that’s good.

Also updated the tests with your exact example to ensure this stays working.

@Saegrov
Copy link
Author

Saegrov commented Feb 5, 2020

@DangoDev Sweet! Thank you very much!

@SRachamim
Copy link

SRachamim commented Jun 24, 2020

Hey! Unfortunately, it seems like additionalProperties is still not supported. It generates an undefined object instead.

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