json-schema-to-typescript icon indicating copy to clipboard operation
json-schema-to-typescript copied to clipboard

Feature request: Emit unsupported JSON-Schema directives as code comments

Open brettz9 opened this issue 6 years ago • 8 comments

For the "Not expressible in TypeScript:" list in the README, I am wondering whether you would be interested in providing default output whereby such items could be expressed as jsdoc comments in the generated output (and if not, at least ensuring that the proposed custom templating in #9 would have enough information provided to it, such as the current schema object, that users could do so themselves).

Even the nestable items, not, oneOf, and dependencies, should, I think, be representable by generating any necessary (non-exported) type structures and referencing them within the comments, e.g., @not AutoGeneratedType1 and then building the necessary (non-exported) interface AutoGeneratedType1. While TypeScript won't use this information outside of allowing it to pass on through, the information will at least be preserved.

I think having a default behavior would be ideal for both facilitating use and reuse of validation keywords within TypeScript comments (if not usable by tooling such as TypeScript itself or other TypeScript parsing and validating tools) and facilitating round-tripping with the likes of typescript-to-json-schema converters.

If you are open to the idea, there is the question of which jsdoc tags to use. One could use one single custom jsdoc tag (e.g., @ts maximum 100, @ts minimum 50) or different custom jsdoc tags (e.g., @ts-maximum 100, @tx-minimum 50 or just @maximum 100, @minimum 50). I believe the existing generic standard jsdocs tag like @description, @classdesc, or @summary would not be ideal candidates here for this kind of info. ~(FWIW, while some parsers like comment-parser assume a tag title to be comprised of \w, looking at jsdoc source, I see any non-whitespace should be allowed in a tag title, so the hyphen example could apparently be supported and not requiring an underscore. This has since been fixed.)~

brettz9 avatar Jun 17 '19 09:06 brettz9

I just noticed that for at least https://github.com/YousefED/typescript-json-schema , they use an unprefixed type, e.g., @minimum: https://github.com/YousefED/typescript-json-schema#annotations

brettz9 avatar Jun 17 '19 10:06 brettz9

And it appears the list might be expanded to mention lack of TypeScript support (or lack of current implementation support?) for the following:

default, exclusiveMaximum/exclusiveMinimum, maxLength/minLength, readOnly/writeOnly, examples, additionalItems/contains, propertyNames, if/then/else, const

brettz9 avatar Jun 17 '19 12:06 brettz9

Ah ok I was wondering why if/then/else didn't work. @bcherny can you help me understand why we cannot support if/then/else using TypeScript? it could be modeled using ORs no?

{
  "title": "Animal",
  "type": "object",
  "required": ["kind"],
  "properties": {"kind": {"enum": ["cat", "dog"]}},
  "allOf": [{
    "if": {"properties": {"kind": {"const": "cat"}}},
    "then": {"properties": {"sound": {"const": "meow"}}},
  }, {
    "if": {"properties": {"kind": {"const": "dog"}}}
    "then"{"properties": {"sound": {"const": "woof"}}},
  }]
}
type Animal = {
    kind: 'cat' | 'dog',
} & ({
    kind: 'cat',
    sound: 'meow',
} | {
    kind: 'dog',
    sound: 'woof',
});

jbwyme avatar Sep 25 '19 18:09 jbwyme

Also interested in this. I'd be happy to implement it if anyone could show me where to start looking

anonimitoraf avatar Nov 29 '19 06:11 anonimitoraf

@anonimitoraf @brettz9 Want to start by spec'ing out JSONSchema properties, and the output that you'd expect for each? That will help guide how we implement this.

bcherny avatar Nov 30 '19 21:11 bcherny

Ah, actually, my mistake for not stating what I'm after. I'm after the implementation of if/then/else. Shall I raise a new issue for that?

anonimitoraf avatar Nov 30 '19 21:11 anonimitoraf

Hi, I'm interested in this feature. @bcherny, As far as spec'ing out the JSONSchema properties, could it not just take any unknown property key and make it an @ comment? For example a schema:

{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "title": "Super Rad Type",
  "type": "object",
  "properties": {
    "myNumber": {
      "type": "number",
      "description": "just some really great description about this number",
      "minimum": 0,
      "default": 0
     },
     "myNumberArray": {
       "type":"array",
       "description": "just some really great description about this number Array",
       "items": {
         "type": "number"
       },
      "unique": true
     }
  }
}

Would produce:

export interface SuperRadType {

  /**
   * myNumber - just some really great description about this number
   * 
   * @default 0
   * @minimum 0
   */  
  myNumber?: number;

  /**
   * myNumberArray - just some really great description about this number Array
   * 
   * @unique
   */  
  myNumberArray?: number[];
}

chrispaterson avatar Jan 21 '20 01:01 chrispaterson

Yes. The description would be enough.

cjonasw avatar May 15 '20 13:05 cjonasw