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

str:str dictionary generates str:str|undefined dictionary in v7.0.0 #1732

Open
1 of 2 tasks
WarpedPixel opened this issue Jun 25, 2024 · 3 comments
Open
1 of 2 tasks
Labels
bug Something isn't working openapi-ts Relevant to the openapi-typescript library

Comments

@WarpedPixel
Copy link

Description

A dictionary of string -> string defined in the openapi.json spec, generates a string -> string | undefined dictionary in Typescript. This worked as expected with 6.7.7.

src/routes/profile-page.vue:84:51 - error TS2322: Type 'string | undefined' is not assignable to type 'string'.
  Type 'undefined' is not assignable to type 'string'.

             state.languageArray.push({value: key, title: data.languages[key]})
Name Version
openapi-typescript 7.0.0
Node.js v20.14.0
OS + version macOS 14.5

Reproduction

Excerpts from openapi.json

"/api/languages": {
    "get": {
        "tags": [
            "root"
        ],
        "summary": "Get Languages",
        "description": "Returns the list of supported languages and their display names in each native language.\nLanguages are IANA language tags with optional territory codes (e.g. 'en', 'en_US', 'pt', 'pt_BR', etc.).\nLanguage names are in each native language or in a specific language if passed in the `lang` parameter).",
        "operationId": "get_languages_api_languages_get",
        "parameters": [
            {
                "name": "lang",
                "in": "query",
                "required": false,
                "schema": {
                    "anyOf": [
                        {
                            "type": "string"
                        },
                        {
                            "type": "null"
                        }
                    ],
                    "title": "Lang"
                }
            }
        ],
        "responses": {
            "200": {
                "description": "Successful Response",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/SupportedLanguages"
                        }
                    }
                }
            },
            "422": {
                "description": "Validation Error",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/HTTPValidationError"
                        }
                    }
                }
            }
        }
    }
}

"SupportedLanguages": {
    "properties": {
        "languages": {
            "additionalProperties": {
                "type": "string"
            },
            "type": "object",
            "title": "Languages"
        }
    },
    "type": "object",
    "required": [
        "languages"
    ],
    "title": "SupportedLanguages"
}

Expected result

Output from 6.7.7:

    /** SupportedLanguages */
    SupportedLanguages: {
      /** Languages */
      languages: {
        [key: string]: string;
      };
    };

Actual result

Output from 7.0.0:

        /** SupportedLanguages */
        SupportedLanguages: {
            /** Languages */
            languages: {
                [key: string]: string | undefined;
            };
        };

Checklist

@WarpedPixel WarpedPixel added bug Something isn't working openapi-ts Relevant to the openapi-typescript library labels Jun 25, 2024
@drwpow
Copy link
Contributor

drwpow commented Jun 26, 2024

I think this is a duplicate of #1727?

@WarpedPixel
Copy link
Author

Seems related for sure. But I don't understand how this is desired behavior. I also wonder how it relates to issue #1018 where it seems things were moving in the direction of removing | undefined not adding it.

I am no Typescript expert, but the intention here is to declare a dictionary, that maps str to str. Not to anything else. It is type checked at the source (Python backend in this case) to ensure that is true.

class SupportedLanguages(BaseModel):
    languages: dict[str, str]

That then becomes an openAPI spec:

"SupportedLanguages": {
    "properties": {
        "languages": {
            "additionalProperties": {
                "type": "string"
            },
            "type": "object",
            "title": "Languages"
        }
    },
    "type": "object",
    "required": [
        "languages"
    ],
    "title": "SupportedLanguages"
}

Which is the way to describe a dictionary in OpenAPI AFAIK.

No dictionary has all the keys, obviously. But in my case, if it has a key it maps to a string.

In fact, in my Typescript code I declare the array that holds the languages as

      languages: {
        [key: string]: string;
      };

The intention was to declare a dictionary that maps certain strings to strings (not to null or undefined). This is now incompatible with the type opeanapi-typescript 7.0.0 creates. This declaration makes languages['some str not in dict'] return undefined, but it prevents me from storing undefined in the dictionary (good). It seems that adding | undefined would not be helpful here in my case.

What is the suggested fix or best practice in this case? Declare all Typescript dictionaries with | undefined? Is there some option to change behavior of openapi-typescript?

@shaunpersad
Copy link

Strong agree with @WarpedPixel. I had to stay on version 6 because of this.

I think the intent vs. the implementation might be confused. I understand that it's an effort to prevent you from assuming a key exists. But simply checking for the existence of the key does not remove the undefined from the union.

Contrast that with what the schema is actually declaring, which is that if a key exists, then here are the only allowed values. undefined makes no sense to include there, because it is not an allowed value for a given key that exists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working openapi-ts Relevant to the openapi-typescript library
Projects
None yet
Development

No branches or pull requests

3 participants