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

Bug: enum with 1 value is not an enum in the JSON schema (evaluates as constant) #577

Open
alita-moore opened this issue Oct 12, 2023 · 2 comments

Comments

@alita-moore
Copy link

Description

When you export an enum with one value it maps to a constant in the schema, but I expect it to map to an enum with one element.

Reproduction

see the reproduction in the following codesandbox: https://codesandbox.io/p/sandbox/lucid-kirch-r3rxlg

in short, the input typescript file is

export enum Test {
  apple = "apple",
}

export enum Test2 {
  apple = "apple",
  orange = "orange",
}

And the command to compile into json schema is

npx typescript-json-schema index.ts '*' -o out/generated.json --required --aliasRefs --refs --titles --propOrder --noExtraProps

Expected Results

I expect the results to be an enum with one element

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "definitions": {
        "Test": {
            "enum": [
                "apple"
            ],
            "type": "string"
        },
        "Test2": {
            "enum": [
                "apple",
                "orange"
            ],
            "type": "string"
        }
    }
}

Actual Results

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "definitions": {
        "Test": {
            "const": "apple",
            "type": "string"
        },
        "Test2": {
            "enum": [
                "apple",
                "orange"
            ],
            "type": "string"
        }
    }
}
@GeekyEggo
Copy link

If the value can only be a single value, I would expect it to be a const. Is there any advantage to having it as a single-element enum?

@alita-moore
Copy link
Author

Using enums in Typescript except a standard string is helpful for many reasons. For example,

1. the ability to add more values in the future without having to change the implementation

type someType = {
key: Enum.Apple,
value: string
}

In the future

type SomeType =
{
key: Enum.Apple
value: string
} | {
key: Enum.Orange
value: number
}

Dependents on SomeType would not need to start using an Enum once the new value is added which reduces overhead.

2. the use of enums in a switch that will error if a case is missed.

switch (EnumValue) {
case Enum.Apple:
Do something
default:
// @ts-expect-error -- this will error if a case is missed above
EnumValue.toString()
}

3. The ability to find the usages of the Enum value easily

By right clicking the Enum definition you can find where in the code that value is indexed. This simplifies finding and replacing usages.

4. Python does not support literal constants

I am using this tool as an interim step to then convert to pydantic. Which means that if it's defined as only a cost and not an Enum then I am unable to enforce the Enum value throughout my python code. That's because you can set the type of a variable in python to the Enum concrete class, but you cannot set the type to a string / const.

This is a few examples but there are more. Using an Enum is helpful even if only one value. Specifically in Typescript. But perhaps a more important point is whether or not it's intuitive for this software to change the input type based on the length of the Enum. It seems to be more intuitive that if an Enum is the input then an Enum will be the output, no?

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

No branches or pull requests

2 participants