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

Export enum name to allow for casting #354

Closed
PerttiK opened this issue Dec 15, 2020 · 4 comments
Closed

Export enum name to allow for casting #354

PerttiK opened this issue Dec 15, 2020 · 4 comments

Comments

@PerttiK
Copy link

PerttiK commented Dec 15, 2020

The following JSON schema

"fruit": {
      "description": "type of fruit",
      "type": "string",
      "enum": [
        "BANANA",
        "KIWI",
        "CHERRY
      ]
    }

is converted to

fruit: "BANANA" | "KIWI" | "CHERRY"

in the generated interface.

That looks good, but this means you can't assign a string (even when the string is "BANANA", "KIWI" or "CHERRY") to an object that adheres to the interface, unless you cast it. However, without the d.ts file exporting the enum type there's no way you can actually cast the string to the enum.
The problem can be solved when json-schema-to-typescript would export the enum as follows

export enum fruit {
  BANANA = "BANANA",
 KIWI = "KIWI",
 CHERRY = "CHERRY"
}

because that would allow consumers of the interface to cast a string to the enum as follows

...
fruitPropertyOfObjectThatShouldAdhereToInterface: <fruit> fruitString,
...

Am I missing something or would this be a much needed improvement?

@PerttiK
Copy link
Author

PerttiK commented Dec 17, 2020

This is similar to #337 except for the suggestion to not even have to rely on propertyNames

@bcherny
Copy link
Owner

bcherny commented Dec 27, 2020

You can do this with tsEnumNames:

Input:

{
  type: 'object',
  properties: {
    fruit: {
      description: 'type of fruit',
      type: 'string',
      enum: ['BANANA', 'KIWI', 'CHERRY']
    },
    fruit2: {
      description: 'type of fruit',
      id: 'Fruit',
      type: 'string',
      enum: ['BANANA', 'KIWI', 'CHERRY'],
      tsEnumNames: ['BANANA', 'KIWI', 'CHERRY']
    }
  }
}

Output:

/* tslint:disable */
/**
 * This file was automatically generated by json-schema-to-typescript.
 * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
 * and run json-schema-to-typescript to regenerate this file.
 */

export interface Demo {
  /**
   * type of fruit
   */
  fruit?: "BANANA" | "KIWI" | "CHERRY";
  fruit2?: Fruit;
  [k: string]: unknown;
}

/**
 * type of fruit
 */
export enum Fruit {
  BANANA = "BANANA",
  KIWI = "KIWI",
  CHERRY = "CHERRY"
}

Adding a new option to generate string enums instead of unions (without needing tsEnumNames) seems reasonable too, if more folks want this.

@PerttiK
Copy link
Author

PerttiK commented Dec 30, 2020

I think it's a really important principle not to have to rely on custom properties in your input JSON schema to end up with an exported named enum in TypeScript that you can use for casting your strings when coding.
As mentioned before this is similar to #337 and actually exactly the same as #200 with 6 upvotes and a pull request that was never merged (#262)

@bcherny
Copy link
Owner

bcherny commented Dec 30, 2020

Sounds good, thanks for the feedback @PerttiK.

I've reopened #200, and am marking this issue as a dup. Feel free to resurrect #262 if you'd like.

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

2 participants