ts-json-schema-generator icon indicating copy to clipboard operation
ts-json-schema-generator copied to clipboard

Don't output intermediate aliases

Open kanitw opened this issue 6 years ago • 10 comments

export interface Parent {
  a: A;
}
export type A = RealA;

export type RealA = { realA: string };
./node_modules/.bin/ts-json-schema-generator \
    --path 'test.ts' \
    --type 'Parent' \
    --expose 'export' \
    --jsDoc 'extended'

outputs

{
  "$ref": "#/definitions/Parent",
  "$schema": "http://json-schema.org/draft-06/schema#",
  "definitions": {
    "A": {
      "$ref": "#/definitions/RealA"
    },
    "Parent": {
      "additionalProperties": false,
      "properties": {
        "a": {
          "$ref": "#/definitions/A"
        }
      },
      "required": [
        "a"
      ],
      "type": "object"
    },
    "RealA": {
      "additionalProperties": false,
      "properties": {
        "realA": {
          "type": "string"
        }
      },
      "required": [
        "realA"
      ],
      "type": "object"
    }
  }
}

However, if RealA is not referred elsewhere, it's better to output:

{
  "$ref": "#/definitions/Parent",
  "$schema": "http://json-schema.org/draft-06/schema#",
  "definitions": {
    "A": {
      "additionalProperties": false,
      "properties": {
        "realA": {
          "type": "string"
        }
      },
      "required": [
        "realA"
      ],
      "type": "object"
    },
    "Parent": {
      "additionalProperties": false,
      "properties": {
        "a": {
          "$ref": "#/definitions/A"
        }
      },
      "required": [
        "a"
      ],
      "type": "object"
    }
    
  }
}

kanitw avatar Mar 10 '19 06:03 kanitw

Note that this is quite important to make the schema legible. (It will reduce number of stacks in JSON schema validation error.)

kanitw avatar Mar 10 '19 17:03 kanitw

So the idea is to never output something of the form

"XXXX": {
 "$ref": "#/definitions/YYYY"
}

and replace all occurrences of XXXX with YYYY

domoritz avatar Mar 25 '19 23:03 domoritz

This works as expected. We output intermediate aliases when they are exported.

You can hide a alias by not exporting it:

export interface Parent {
    a: A;
}
export type A = RealA;

type RealA = { realA: string };

I think only exporting types that are used more than once is going to be more surprising (and hard to implement).

domoritz avatar Sep 20 '19 01:09 domoritz

Well, in Vega-Lite use case, we need the intermediate ones because RealA is generic and A is an alias for a specific form of generic.

Thus, we can't really avoid exporting the generic.

kanitw avatar Sep 24 '19 03:09 kanitw

Hmm, I guess we could use the @hide annotation here to skip aliases. I don't think hiding an alias that's only used once is a good idea since it may be desired by the developer.

domoritz avatar Sep 26 '19 02:09 domoritz

FWIW, adding @hide to RealA currently doesn't skip aliases.

kanitw avatar Sep 26 '19 23:09 kanitw

Yep, we only respect @hide for properties right now. I suggest that we also use it to ignore aliases. Would that be the solution that we want?

domoritz avatar Sep 26 '19 23:09 domoritz

I guess that sounds good to me.

I don't know if/how @hide currently works for aliases at all.

kanitw avatar Sep 27 '19 03:09 kanitw

It doesn't. We only use it for properties of objects and interfaces.

domoritz avatar Sep 27 '19 04:09 domoritz

and interfaces

Oh well, it's worth noting that we actually want to keep the alias and hide the original interface.

Like hiding RealA and keep only A in the example above.

But more practical use case is to think if we have GenericA<T> and type A = Generic<string>, then we want to only keep A.

I don't think hiding an alias that's only used once is a good idea since it may be desired by the developer.

I'd argue that in most cases, there is no good reason for the developer to want to keep the chaining since "an alias that's only used once" means that all references of the original interface is called via the alias, but the schema simply treat the alias as chaining more than real "alias".

kanitw avatar Sep 27 '19 06:09 kanitw