bcherny / json-schema-to-typescript

Compile JSON Schema to TypeScript type declarations
https://bcherny.github.io/json-schema-to-typescript-browser/
MIT License
2.95k stars 392 forks source link

Referencing specific enum values? #600

Closed a0js closed 5 months ago

a0js commented 5 months ago

Is it possible to reference a specific enum value that is defined in another referenced definition? For example in defining a discriminating union:

const schema = {
  title: "OptionRestrictions"
  oneOf: [
    {
      type:"object",
      properties: {
        option: {
          const: <reference enum value Square here>
        },
        length: {
          type: 'number'
        }
      }
    },
    {
      type:"object",
      properties: {
        option: {
          const: <reference enum value Circle here>
        },
        radius: {
          type: 'number'
        }
      }
    }
  ],
  definitions: {
    options: {
      title: "Options",
      type: "string",
      enum: ['square','circle',],
      tsEnumNames: ['Square','Circle']
    }
  }
}

Ideally it would output something like this:

export const enum Options {
  Square = 'square'.
  Circle = 'circle'
}
export type OptionRestrictions =
  |  {
        option: Options.Square,
        length: 'number'
     }
  |  {
       option: Options.Circle,
       radius: 'number'
     };
bcherny commented 5 months ago

You can do something like this:

{
  "title": "Example Schema",
  "type": "object",
  "definitions": {
    "circle": {
      "type": "string",
      "enum": [
        "circle"
      ]
    },
    "square": {
      "type": "string",
      "enum": [
        "square"
      ]
    },
    "shape": {
      "oneOf": [
        {
          "$ref": "#/definitions/circle"
        },
        {
          "$ref": "#/definitions/square"
        }
      ]
    }
  },
  "properties": {
    "shape": {
      "$ref": "#/definitions/shape"
    }
  }
}

=>

/* eslint-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 type Shape = Circle | Square;
export type Circle = "circle";
export type Square = "square";

export interface ExampleSchema {
  shape?: Shape;
  [k: string]: unknown;
}

https://borischerny.com/json-schema-to-typescript-browser/#schema=%7B%0A%20%20%22title%22:%20%22Example%20Schema%22,%0A%20%20%22type%22:%20%22object%22,%0A%20%20%22definitions%22:%20%7B%0A%20%20%20%20%22circle%22:%20%7B%0A%20%20%20%20%20%20%22type%22:%20%22string%22,%0A%20%20%20%20%20%20%22enum%22:%20%5B%0A%20%20%20%20%20%20%20%20%22circle%22%0A%20%20%20%20%20%20%5D%0A%20%20%20%20%7D,%0A%20%20%20%20%22square%22:%20%7B%0A%20%20%20%20%20%20%22type%22:%20%22string%22,%0A%20%20%20%20%20%20%22enum%22:%20%5B%0A%20%20%20%20%20%20%20%20%22square%22%0A%20%20%20%20%20%20%5D%0A%20%20%20%20%7D,%0A%20%20%20%20%22shape%22:%20%7B%0A%20%20%20%20%20%20%22oneOf%22:%20%5B%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%22$ref%22:%20%22#/definitions/circle%22%0A%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%22$ref%22:%20%22#/definitions/square%22%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%5D%0A%20%20%20%20%7D%0A%20%20%7D,%0A%20%20%22properties%22:%20%7B%0A%20%20%20%20%22shape%22:%20%7B%0A%20%20%20%20%20%20%22$ref%22:%20%22#/definitions/shape%22%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D

a0js commented 5 months ago

Thank you @bcherny!