json-schema-to-typescript
json-schema-to-typescript copied to clipboard
Feature request: Emit unsupported JSON-Schema directives as code 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.)~
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
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
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',
});
Also interested in this. I'd be happy to implement it if anyone could show me where to start looking
@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.
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?
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[];
}
Yes. The description would be enough.