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

Named enum for string type #60

Closed
java2kus opened this issue Jan 29, 2017 · 8 comments
Closed

Named enum for string type #60

java2kus opened this issue Jan 29, 2017 · 8 comments

Comments

@java2kus
Copy link

How do I generate named enums for string types. My JSON Schema looks like below:

"status": {
      "enum": [
        "I",
        "A",
        "C"
      ],
      "tsEnumNames": [
        "InProgress",
        "ForApproval",
        "Complete"
      ]
    },

Should generate the following Typescript

  status: Status
....
export const enum Status {
   InProgress = "I"
   ForApproval = "A"
   Complete = "C"
}

Instead of the above, its generating the flags without quotes that results in TypeScript error. Can you please suggest, how can I generate the above typescript code?

@java2kus java2kus changed the title Named enum for string types Named enum for string type Jan 29, 2017
@bcherny
Copy link
Owner

bcherny commented Jan 29, 2017

Hi @java2kus! TypeScript (like Java) does not support String => String enums. Enums in TS must be String => Number; see https://www.typescriptlang.org/docs/handbook/enums.html.

You have a few options:

  1. Use numerical values for your enum. Eg.
"status": {
  "enum": [1, 2, 3],
  "tsEnumNames": ["InProgress", "ForApproval", "Complete"]
}

=> export const enum Status {
  InProgress = 1,
  ForApproval = 2,
  Complete = 3
}

export interface MyInterface {
  status: Status
}
  1. Use a union of string literal types. Eg.
"status": {
  "enum": ["InProgress", "ForApproval", "Complete"]
}

=> export interface MyInterface {
  status: "InProgress" | "ForApproval" | "Complete"
}

See all the valid ways to generate enums with json-schema-to-ts here.

Hope that helps!

@java2kus
Copy link
Author

@bcherny Thanks a lot for clarifying. Coming from a Java programming background, I am trying to wrap my head around Typescript :-). I guess I cannot solve my specific problem of substitution. But how I can achieve type safety on passing functions for the above.

e.g. I am trying to create a function where one of the parameters is status. Currently I am defining this separately by adding a type like this which is leading to a lot of boilerplate and repetition in my code. In my case MyInterface has many more properties like taskDescription etc.

If the generated interface above generates types for String literals my problem will be solved. Can you please let me know if this can be achieved in any way?

  "taskDescription": {
      "type": "string"
  }
  "status": {
          "enum": ["InProgress", "ForApproval", "Complete"]
   }
==>
   export type Status = "InProgress" | "ForApproval" | "Complete";

    export interface MyInterface {
       taskDescription: string;
       status: Status;
    
   }
.....
    generateEvent(status: Status, taskDescription: string) {  ... }

@bcherny
Copy link
Owner

bcherny commented Jan 31, 2017

@java2kus I'm not sure I understand what you're trying to do. The code you gave above will compile perfectly, is there something more you're trying to generate?

@java2kus
Copy link
Author

@bcherny I was checking if the above code can be generated using json-schema-to-typescript library. Right now after the code generation, I am manually making all the above changes in my code.

@bcherny
Copy link
Owner

bcherny commented Jan 31, 2017

There is no support for named union types today.

"taskDescription": {
      "type": "string"
  }
  "status": {
          "enum": ["InProgress", "ForApproval", "Complete"]
   }

Will generate

export interface MyInterface {
  taskDescription: string;
  status: "InProgress" | "ForApproval" | "Complete";
}

@java2kus
Copy link
Author

@bcherny This is how I have manually coded the string based enums in Typescript. I thought it would be useful for any future code generation enhancements. I am using Typescript 2.2.

export enum Status {
  InProgress = <any> 'I',
  ForApproval = <any> 'A',
  Complete = <any> 'C'
}

@bcherny
Copy link
Owner

bcherny commented Feb 23, 2017

@java2kus I don't think that actually works. It tricks the compiler into compiling the enum, but you don't get any type safety with it. What you want is microsoft/TypeScript#1206, or restructuring your code to use a number enum/union of string literal types.

export enum Status {
  InProgress = <any> 'I',
  ForApproval = <any> 'A',
  Complete = <any> 'C'
}

Status.A // Error

if (Status.InProgress === 'I') { } // Error

@pasawant
Copy link

pasawant commented Feb 18, 2021

@bcherny i too wanted to generate string enum from schema:

https://www.typescriptlang.org/docs/handbook/enums.html#string-enums
End goal is the get below code generated :

export enum DataType {
  Boolean = 'b',
  Date = 'd',
  DateTime = 'D',
  Number = 'n',
  String = 's'
}

Can you suggest some example for this?

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

3 participants