Giter VIP home page Giter VIP logo

typescript-json-schema's Introduction

typescript-json-schema

npm version Test

Generate json-schemas from your Typescript sources.

Features

  • Compiles your Typescript program to get complete type information.
  • Translates required properties, extends, annotation keywords, property initializers as defaults. You can find examples for these features in the api doc or the test examples.

Usage

Command line

  • Install with npm install typescript-json-schema -g
  • Generate schema from a typescript type: typescript-json-schema project/directory/tsconfig.json TYPE

To generate files for only some types in tsconfig.json specify filenames or globs with the --include option. This is especially useful for large projects.

In case no tsconfig.json is available for your project, you can directly specify the .ts files (this in this case we use some built-in compiler presets):

  • Generate schema from a typescript type: typescript-json-schema "project/directory/**/*.ts" TYPE

The TYPE can either be a single, fully qualified type or "*" to generate the schema for all types.

Usage: typescript-json-schema <path-to-typescript-files-or-tsconfig> <type>

Options:
  --refs                Create shared ref definitions.                               [boolean] [default: true]
  --aliasRefs           Create shared ref definitions for the type aliases.          [boolean] [default: false]
  --topRef              Create a top-level ref definition.                           [boolean] [default: false]
  --titles              Creates titles in the output schema.                         [boolean] [default: false]
  --defaultProps        Create default properties definitions.                       [boolean] [default: false]
  --noExtraProps        Disable additional properties in objects by default.         [boolean] [default: false]
  --propOrder           Create property order definitions.                           [boolean] [default: false]
  --required            Create required array for non-optional properties.           [boolean] [default: false]
  --strictNullChecks    Make values non-nullable by default.                         [boolean] [default: false]
  --esModuleInterop     Use esModuleInterop when loading typescript modules.         [boolean] [default: false]
  --skipLibCheck        Use skipLibCheck when loading typescript modules.            [boolean] [default: false]
  --useTypeOfKeyword    Use `typeOf` keyword (https://goo.gl/DC6sni) for functions.  [boolean] [default: false]
  --out, -o             The output file, defaults to using stdout
  --validationKeywords  Provide additional validation keywords to include            [array]   [default: []]
  --include             Further limit tsconfig to include only matching files        [array]   [default: []]
  --ignoreErrors        Generate even if the program has errors.                     [boolean] [default: false]
  --excludePrivate      Exclude private members from the schema                      [boolean] [default: false]
  --uniqueNames         Use unique names for type symbols.                           [boolean] [default: false]
  --rejectDateType      Rejects Date fields in type definitions.                     [boolean] [default: false]
  --id                  Set schema id.                                               [string]  [default: ""]
  --defaultNumberType   Default number type.                                         [choices: "number", "integer"] [default: "number"]
  --tsNodeRegister      Use ts-node/register (needed for require typescript files).  [boolean] [default: false]
  --constAsEnum         Use enums with a single value when declaring constants.      [boolean] [default: false]
  --experimentalDecorators  Use experimentalDecorators when loading typescript modules.
   [boolean] [default: true]

Programmatic use

import { resolve } from "path";

import * as TJS from "typescript-json-schema";

// optionally pass argument to schema generator
const settings: TJS.PartialArgs = {
    required: true,
};

// optionally pass ts compiler options
const compilerOptions: TJS.CompilerOptions = {
    strictNullChecks: true,
};

// optionally pass a base path
const basePath = "./my-dir";

const program = TJS.getProgramFromFiles(
  [resolve("my-file.ts")],
  compilerOptions,
  basePath
);

// We can either get the schema for one file and one type...
const schema = TJS.generateSchema(program, "MyType", settings);

// ... or a generator that lets us incrementally get more schemas

const generator = TJS.buildGenerator(program, settings);

// generator can be also reused to speed up generating the schema if usecase allows:
const schemaWithReusedGenerator = TJS.generateSchema(program, "MyType", settings, [], generator);

// all symbols
const symbols = generator.getUserSymbols();

// Get symbols for different types from generator.
generator.getSchemaForSymbol("MyType");
generator.getSchemaForSymbol("AnotherType");
// In larger projects type names may not be unique,
// while unique names may be enabled.
const settings: TJS.PartialArgs = {
    uniqueNames: true,
};

const generator = TJS.buildGenerator(program, settings);

// A list of all types of a given name can then be retrieved.
const symbolList = generator.getSymbols("MyType");

// Choose the appropriate type, and continue with the symbol's unique name.
generator.getSchemaForSymbol(symbolList[1].name);

// Also it is possible to get a list of all symbols.
const fullSymbolList = generator.getSymbols();

getSymbols('<SymbolName>') and getSymbols() return an array of SymbolRef, which is of the following format:

type SymbolRef = {
    name: string;
    typeName: string;
    fullyQualifiedName: string;
    symbol: ts.Symbol;
};

getUserSymbols and getMainFileSymbols return an array of string.

Annotations

The schema generator converts annotations to JSON schema properties.

For example

export interface Shape {
    /**
     * The size of the shape.
     *
     * @minimum 0
     * @TJS-type integer
     */
    size: number;
}

will be translated to

{
    "$ref": "#/definitions/Shape",
    "$schema": "http://json-schema.org/draft-07/schema#",
    "definitions": {
        "Shape": {
            "properties": {
                "size": {
                    "description": "The size of the shape.",
                    "minimum": 0,
                    "type": "integer"
                }
            },
            "type": "object"
        }
    }
}

Note that we needed to use @TJS-type instead of just @type because of an issue with the typescript compiler.

You can also override the type of array items, either listing each field in its own annotation or one annotation with the full JSON of the spec (for special cases). This replaces the item types that would have been inferred from the TypeScript type of the array elements.

Example:

export interface ShapesData {
    /**
     * Specify individual fields in items.
     *
     * @items.type integer
     * @items.minimum 0
     */
    sizes: number[];

    /**
     * Or specify a JSON spec:
     *
     * @items {"type":"string","format":"email"}
     */
    emails: string[];
}

Translation:

{
    "$ref": "#/definitions/ShapesData",
    "$schema": "http://json-schema.org/draft-07/schema#",
    "definitions": {
        "Shape": {
            "properties": {
                "sizes": {
                    "description": "Specify individual fields in items.",
                    "items": {
                        "minimum": 0,
                        "type": "integer"
                    },
                    "type": "array"
                },
                "emails": {
                    "description": "Or specify a JSON spec:",
                    "items": {
                        "format": "email",
                        "type": "string"
                    },
                    "type": "array"
                }
            },
            "type": "object"
        }
    }
}

This same syntax can be used for contains and additionalProperties.

integer type alias

If you create a type alias integer for number it will be mapped to the integer type in the generated JSON schema.

Example:

type integer = number;
interface MyObject {
    n: integer;
}

Note: this feature doesn't work for generic types & array types, it mainly works in very simple cases.

require a variable from a file

(for requiring typescript files is needed to set argument tsNodeRegister to true)

When you want to import for example an object or an array into your property defined in annotation, you can use require.

Example:

export interface InnerData {
    age: number;
    name: string;
    free: boolean;
}

export interface UserData {
    /**
     * Specify required object
     *
     * @examples require("./example.ts").example
     */
    data: InnerData;
}

file example.ts

export const example: InnerData[] = [{
  age: 30,
  name: "Ben",
  free: false
}]

Translation:

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "properties": {
        "data": {
            "description": "Specify required object",
            "examples": [
                {
                    "age": 30,
                    "name": "Ben",
                    "free": false
                }
            ],
            "type": "object",
            "properties": {
                "age": { "type": "number" },
                "name": { "type": "string" },
                "free": { "type": "boolean" }
            },
            "required": ["age", "free", "name"]
        }
    },
    "required": ["data"],
    "type": "object"
}

Also you can use require(".").example, which will try to find exported variable with name 'example' in current file. Or you can use require("./someFile.ts"), which will try to use default exported variable from 'someFile.ts'.

Note: For examples a required variable must be an array.

Background

Inspired and builds upon Typson, but typescript-json-schema is compatible with more recent Typescript versions. Also, since it uses the Typescript compiler internally, more advanced scenarios are possible. If you are looking for a library that uses the AST instead of the type hierarchy and therefore better support for type aliases, have a look at vega/ts-json-schema-generator.

Debugging

npm run debug -- test/programs/type-alias-single/main.ts --aliasRefs true MyString

And connect via the debugger protocol.

typescript-json-schema's People

Contributors

benny-medflyt avatar bobocandys avatar dependabot[bot] avatar dobesv avatar domoritz avatar fabiandev avatar fischeversenker avatar forbeslindesay avatar garyevari avatar joshkel avatar jwatzman avatar lundibundi avatar marcprux avatar marcusriemer avatar martin-tichovsky-s2 avatar navossoc avatar netanel-mce avatar nfour avatar otgerrogla avatar random42 avatar remcohaszing avatar richardkazuomiller avatar rmehner avatar robertmassaioli avatar rohantalip avatar rpetrich avatar ryanlb avatar schani avatar wenliangcan avatar yousefed avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

typescript-json-schema's Issues

Specifically allow additionalProperties on certain types?

I usually run the generator using --noExtraProps true as I don't want the API these schemas are protecting to silently discard unknown data. This works great in general, but fails in one specific cornercase: In one type I need to allow extra fields as part of a general key-value store.

In Typescript, I expressed this as

/**
 * A widget **requires** at least a type, all other fields are
 * mandated by deriving descriptions.
 */
export interface WidgetDescription {
    type : string
    [x: string]: any 
}

Adding additional fields to this works fine in code:

const foo : WidgetDescription = {
    type : "test",
    additional : 2
}

But the generated schema does not allow any additional properties:

    "WidgetDescription": {
        "type": "object",
        "properties": {
            "type": {
                "type": "string"
            }
        },
        "additionalProperties": false
    }

I am not quite sure how to correctly tackle this case in JSON schema. But from my understanding the presence of a property-specification like [x: string]: any could translate to additionalProperties: true.

Providing specific project files using glob

Tried to run the command in a subdirectory because I have multiple interfaces with the same name in different directories. I followed the instructions in the README and formatted the command thusly:

 typescript-json-schema src/mappings/draft-3/*.ts Workflow

However, I get this error.

                throw "type " + symbolName + " not found";
                ^
type src/mappings/draft-3/ArraySchema.ts not found

After some digging around in the code, I realized that the glob is expanded and supplied to the args, so the first x arguments of the command line are actually all the files that match the glob. This is actually expected glob behavior in bash. The specified type is all the way at the end of the args array, and not the second argument as expected.

My question: was this not the intended usage of a specific path or should the documentation be updated?

Thanks! Great work, by the way. 👍

nullable by type

In this case

export interface Person {
    /** @nullable */
    name?: string;
}

allowed types art string and null.

There

export interface Person {
    name?: null;
}

allowed type is null.

But there

export interface Person {
    name?: string | null;
}

only string will be allowed.

Script should not skip null type if any other type is provided.

Temporary workaround - provide type information and @nullable notation.

export interface Person {
    /** @nullable */
    name?: string | null;
}

Update to typescript 2.0.

Typescript 2.0 has been recently released, would it make sense to upgrade the library? I tried 2.0 locally, so far so good.

@nullable annotations wrong for references

interface MyType {
    foo: number;
};

interface MyObject {
    /**
     * @nullable
     */
    var1: MyType;
    var2: MyType;
}

Output

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "definitions": {
        "MyType": {
            "anyOf": [
                {
                    "properties": {
                        "foo": {
                            "type": "number"
                        }
                    },
                    "required": [
                        "foo"
                    ],
                    "type": "object"
                },
                {
                    "type": "null"
                }
            ]
        }
    },
    "properties": {
        "var1": {
            "$ref": "#/definitions/MyType"
        },
        "var2": {
            "$ref": "#/definitions/MyType"
        }
    },
    "required": [
        "var1",
        "var2"
    ],
    "type": "object"
}

In this case the MyType becomes nullable and not just var1. This causes issues for example in vega/vega-lite#1706

Suggestion: make the generator engine external module

It would be nice if the generator was external node module, usable as in javascript code.
I'm thinking about generating my schemes dynamically from the ts on build time as webpack loader or so.
And also will be usable as gulp task

Aliased types at the root don't create correct schema

interface MyObject {
    prop: number;
}

type MyAlias = MyObject;
ts-node typescript-json-schema.ts --topRef true --aliasRefs true test/programs/type-aliases-alias-ref-topref/main.ts  MyAlias

Expect

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "definitions": {
        "MyObject": {
            "type": "object",
            "properties": {
                "prop": {
                    "type": "number"
                }
            },
            "required": [
                "prop"
            ]
        },
        "MyAlias": {
            "$ref": "#/definitions/MyObject"
        }
    },
    "$ref": "#/definitions/MyAlias"
}

But get

{
    "$ref": "#/definitions/MyObject",
    "$schema": "http://json-schema.org/draft-04/schema#",
    "definitions": {
        "MyObject": {
            "properties": {
                "prop": {
                    "type": "number"
                }
            },
            "type": "object"
        }
    }
}

Extension to pr #55 and comments-override

Although @MarcusRiemer's fix for comments, shown in the test for comments-override, is great for extending interfaces, it fails to account for types. Here is an example:

/**
 * @type integer
 * @minimum 1
 */
export type PositiveInteger = number;

export interface MyObject {
  user_ids: PositiveInteger[];
  user_id: PositiveInteger;
}

and the expected schema is:

{
    "type": "object",
    "properties": {
        "user_ids": {
            "type": "array",
            "items": {
                "$ref": "#/definitions/PositiveInteger"
            }
        },
        "user_id": {
          "$ref": "#/definitions/PositiveInteger"
        }
    },
    "required": [
        "company_ids",
        "user_id"
    ],
    "definitions": {
        "PositiveInteger": {
            "type": "integer",
            "minimum": 1
        }
    },
    "$schema": "http://json-schema.org/draft-04/schema#"
}

Instead, the result looks like:

{
    "type": "object",
    "properties": {
        "user_ids": {
          "type": "array",
          "items": {
              "type": "number"
          }
        },
        "user_id": {
            "minimum": 1,
            "type": "integer"
        }
    },
    "required": [
        "user_ids",
        "user_id"
    ],
    "$schema": "http://json-schema.org/draft-04/schema#"
}

If I have a minute, I'll look into this, but a little busy. Probably isn't too complicated

Fails on string literal union types

This seems to fail when using a union of string literal types.

interface Test {
    first: 'a'; // works
    second: 'a' | 'b'; // fails
}

The error is:

/usr/lib/node_modules/typescript-json-schema/node_modules/typescript/lib/typescript.js:15712
            return symbol.parent ? getFullyQualifiedName(symbol.parent) + "." + symbolToString(symbol) : symbolToString(symbol);
                         ^

TypeError: Cannot read property 'parent' of null
    at Object.getFullyQualifiedName (/usr/lib/node_modules/typescript-json-schema/node_modules/typescript/lib/typescript.js:15712:26)
    at JsonSchemaGenerator.getTypeDefinition (/usr/lib/node_modules/typescript-json-schema/typescript-json-schema.js:315:35)
    at JsonSchemaGenerator.getDefinitionForProperty (/usr/lib/node_modules/typescript-json-schema/typescript-json-schema.js:154:35)
    at /usr/lib/node_modules/typescript-json-schema/typescript-json-schema.js:258:41
    at Array.reduce (native)
    at JsonSchemaGenerator.getClassDefinition (/usr/lib/node_modules/typescript-json-schema/typescript-json-schema.js:256:49)
    at JsonSchemaGenerator.getTypeDefinition (/usr/lib/node_modules/typescript-json-schema/typescript-json-schema.js:356:26)
    at JsonSchemaGenerator.getDefinitionForRootType (/usr/lib/node_modules/typescript-json-schema/typescript-json-schema.js:131:49)
    at JsonSchemaGenerator.getTypeDefinition (/usr/lib/node_modules/typescript-json-schema/typescript-json-schema.js:350:26)
    at JsonSchemaGenerator.getDefinitionForProperty (/usr/lib/node_modules/typescript-json-schema/typescript-json-schema.js:154:35)

`| null`

type MyType1 = string | null;

type MyType2 = string | number | null;

type MyType3 = string | number[] | null;

type MyType4 = number[] | null;

type Ref = { foo: number };

type MyType5 = Ref | null;


interface MyObject
{
    var1 : MyType1;
    var2 : MyType2;
    var3 : MyType3;
    var4 : MyType4;
    var5 : MyType5;
}

I'd expect this to behave the same as @nullable but somehow adding | null has no effect. Can somebody explain?

Generates wrong schema for readonly arrays

Very, very nice project! The generated code is however wrong for typescripts buildin ReadonlyArray type. If I generate a schema for BuggyType below it will be very strange. It looks like it does not understand that ReadonlyArray is just like an array except that typescript wont allow it to change.

Nb. tested with typescript 2.1.5 and typescript-json-schema 0.7.0

Test input:

export interface BuggyType  {
  readonly single: string;
  readonly multiple: ReadonlyArray<string>;
}

Wrong output:

{
  "type": "object",
  "properties": {
    "single": {
      "type": "string"
    },
    "multiple": {
      "$ref": "#/definitions/ReadonlyArray<string>"
    }
  },
  "additionalProperties": false,
  "required": [
    "single",
    "multiple"
  ],
  "definitions": {
    "ReadonlyArray<string>": {
      "type": "object",
      "properties": {
        "find": {
          "description": "Returns the value of the first element in the array where predicate is true, and undefined\notherwise.",
          "type": "object",
          "properties": {},
          "additionalProperties": false
        },
        "findIndex": {
          "description": "Returns the index of the first element in the array where predicate is true, and -1\notherwise.",
          "type": "object",
          "properties": {},
          "additionalProperties": false
        },
        "length": {
          "description": "Gets the length of the array. This is a number one higher than the highest element defined in an array.",
          "type": "number"
        },
        "toString": {
          "description": "Returns a string representation of an array.",
          "type": "object",
          "properties": {},
          "additionalProperties": false
        },
        "toLocaleString": {
          "type": "object",
          "properties": {},
          "additionalProperties": false
        },
        "concat": {
          "description": "Combines two or more arrays.\nCombines two or more arrays.\nCombines two or more arrays.",
          "type": "object",
          "properties": {},
          "additionalProperties": false
        },
        "join": {
          "description": "Adds all the elements of an array separated by the specified separator string.",
          "type": "object",
          "properties": {},
          "additionalProperties": false
        },
        "slice": {
          "description": "Returns a section of an array.",
          "type": "object",
          "properties": {},
          "additionalProperties": false
        },
        "indexOf": {
          "description": "Returns the index of the first occurrence of a value in an array.",
          "type": "object",
          "properties": {},
          "additionalProperties": false
        },
        "lastIndexOf": {
          "description": "Returns the index of the last occurrence of a specified value in an array.",
          "type": "object",
          "properties": {},
          "additionalProperties": false
        },
        "every": {
          "description": "Determines whether all the members of an array satisfy the specified test.",
          "type": "object",
          "properties": {},
          "additionalProperties": false
        },
        "some": {
          "description": "Determines whether the specified callback function returns true for any element of an array.",
          "type": "object",
          "properties": {},
          "additionalProperties": false
        },
        "forEach": {
          "description": "Performs the specified action for each element in an array.",
          "type": "object",
          "properties": {},
          "additionalProperties": false
        },
        "map": {
          "description": "Calls a defined callback function on each element of an array, and returns an array that contains the results.",
          "type": "object",
          "properties": {},
          "additionalProperties": false
        },
        "filter": {
          "description": "Returns the elements of an array that meet the condition specified in a callback function.\nReturns the elements of an array that meet the condition specified in a callback function.",
          "type": "object",
          "properties": {},
          "additionalProperties": false
        },
        "reduce": {
          "description": "Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\nCalls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.",
          "type": "object",
          "properties": {},
          "additionalProperties": false
        },
        "reduceRight": {
          "description": "Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\nCalls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.",
          "type": "object",
          "properties": {},
          "additionalProperties": false
        }
      },
      "additionalProperties": false,
      "required": [
        "find",
        "findIndex",
        "length",
        "toString",
        "toLocaleString",
        "concat",
        "join",
        "slice",
        "indexOf",
        "lastIndexOf",
        "every",
        "some",
        "forEach",
        "map",
        "filter",
        "reduce",
        "reduceRight"
      ]
    }
  },
  "$schema": "http://json-schema.org/draft-04/schema#"
}

typescript-json-schema bin doesn't work on Linux Mint/bash

First, glad to see someone pick up the torch from typson!

The commandline executable typescript-json-schema doesn't work in Linux Mint 17.

I think this is due to the BOM at the beginning of the file. Recommend removing it. Maybe it's an artifact left by Visual Studio or something?

$ typescript-json-schema 
/usr/bin/typescript-json-schema: line 1: #!/usr/bin/env: No such file or directory
/usr/bin/typescript-json-schema: line 2: syntax error near unexpected token `$'{\r''
'usr/bin/typescript-json-schema: line 2: `if (process.argv[2] !== undefined && process.argv[3] !== undefined) {

I can submit a pr if you'd like.

using $ref in generated schema

typson seems to use $ref by default to refer to other types.

typescript-json-schema defaults to defining one big json-schema type with the dependencies defined inline.

Does tjs (typescript-json-schema; too long to type) support this style or is it planned? I was expecting it to output something very similar to typson by default?

merge main logic for types to schema

some functions are not neatly organized. Reconsider:

getTypeDefinition
getDefinitionForType
getClassDefinition

Some logic here should be merged

Use programmatically

I had an idea about instead of generating the schemas with the CLI, let the application parse his own interfaces and load the schema as objects at runtime, so they can be passed to https://www.npmjs.com/package/jsonschema. That would basically allow to do assertions at runtime against TypeScript interfaces instead of compile time. Is this possible?

Override type feature ?

I would like to be able to override input and output when generating schemas. I am not sure how it should look like in details (or how to implement such a feature):

Overriding input:
I have some complex typescript definitions, where I would like to dynamically replace one typescript type definition with another when generating schemas (for instance dynamically replacing a specific typescript type "xxx" with type "any") in the input for the generated schema.

Overriding output
I have some typescript definitions where a corresponding schema file already exist that is official or better at representing json schema definitions for a property in a typescript interface. For instance, If I use an unofficial typescript type to represent a json schema like this one, I would like property type references for this JsonSchema type to be converted into one of the official json schema meta schema files around rather than typescript-json-schema producing it's own unofficial version (this is likely not be 100% correct anyway.

Wrong schema produced

I am not sure exactly what is wrong but if I use typescript-json-schema to output a schema for a (complex) guimodel from the open source json-schema-js-gui-model project(see type definitions below), the resulting schema does not work (unexpected validation errors in multiple validators like for example the online http://www.jsonschemavalidator.net/).

I fail to understand what exactly is wrong with the generated schema (apart from strangely named TypedField which may/may not be correct) ? Can someone see what is wrong from the type, generated schema and sample input (that I expect to be valid) ?

P.S. If it is a simple problem I can help fix it but would likely need some help as I have only made one small contribution to this project and don't fully understand the codebase.

Typescript GuiModel input definition:

export type ControlType =
    'group' | 'input' | 'dropdown' | 'yesno';

export type DataType =
     'string' | 'number' | 'integer' | 'boolean';

export type StringSubDataType =
    'text'
    | 'password'
    | 'date'
    | 'time'
    | 'date-time'
    | 'uri'
    | 'email'
    | 'hostname'
    | 'ipv4'
    | 'ipv6'
    | 'regex'
    | 'uuid'
    | 'json-pointer'
    | 'relative-json-pointer'
    ;

export type IntegerSubType =
      'port-number'
    | 'miliseconds'
    | 'seconds'
    | 'minutes'
    | 'hours'
    | 'days'
    ;

export type SubDataType = StringSubDataType | IntegerSubType | 'none';

export interface GuiElementBase {
  readonly name: string;

  readonly controlType: ControlType;

  readonly label: string;
  readonly tooltip: string;

  readonly dataObjectPath: string;
  readonly required: boolean;
}

export interface FieldBase extends GuiElementBase {
  readonly kind: 'field';
  readonly type: DataType;
  readonly subType: SubDataType;
};

export interface TypedField<T> extends FieldBase {
  readonly defaultValue: T;
  readonly values?: ReadonlyArray<T>;
}

export interface Group extends GuiElementBase {
  readonly kind: 'group';
  readonly elements: ReadonlyArray<GuiElement>;
}

export interface TranslationError {
  readonly schemaPath: string;
  readonly errorText: string;
};

export interface GuiModel extends Group {
  readonly errors: ReadonlyArray<TranslationError>;
}

export type Field = TypedField<string> | TypedField<number> | TypedField<boolean>;
export type GuiElement = Group | Field;

**Generated schema (note strangely named generic definitions TypedField) **

{
  "description": "Represents a full gui model. Essentially a group but with an extra errors field.",
  "type": "object",
  "properties": {
    "errors": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/TranslationError"
      },
      "title": "errors"
    },
    "kind": {
      "type": "string",
      "enum": [
        "group"
      ],
      "title": "kind"
    },
    "elements": {
      "type": "array",
      "items": {
        "anyOf": [
          {
            "$ref": "#/definitions/Group"
          },
          {
            "$ref": "#/definitions/TypedField<string>"
          },
          {
            "$ref": "#/definitions/TypedField<number>"
          },
          {
            "$ref": "#/definitions/TypedField<boolean>"
          }
        ]
      },
      "title": "elements"
    },
    "name": {
      "type": "string",
      "title": "name"
    },
    "controlType": {
      "$ref": "#/definitions/ControlType",
      "title": "controlType"
    },
    "label": {
      "type": "string",
      "title": "label"
    },
    "tooltip": {
      "type": "string",
      "title": "tooltip"
    },
    "dataObjectPath": {
      "description": "A string representing a path to the property in json data file conforming to the plugin schema,\nwhere each path component is seperated by a dot. Same as string representation of\nLodash.get method or mariocasciaro's object-path (https://github.com/mariocasciaro/object-path).\nThis string is unique for all elements in a model and may thus be used as a key if needed.",
      "type": "string",
      "title": "dataObjectPath"
    },
    "required": {
      "type": "boolean",
      "title": "required"
    }
  },
  "additionalProperties": false,
  "required": [
    "errors",
    "kind",
    "elements",
    "name",
    "controlType",
    "label",
    "tooltip",
    "dataObjectPath",
    "required"
  ],
  "definitions": {
    "TranslationError": {
      "title": "TranslationError",
      "type": "object",
      "properties": {
        "schemaPath": {
          "type": "string",
          "title": "schemaPath"
        },
        "errorText": {
          "type": "string",
          "title": "errorText"
        }
      },
      "additionalProperties": false,
      "required": [
        "schemaPath",
        "errorText"
      ]
    },
    "Group": {
      "description": "A containers for other gui elements.",
      "title": "Group",
      "type": "object",
      "properties": {
        "kind": {
          "type": "string",
          "enum": [
            "group"
          ],
          "title": "kind"
        },
        "elements": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "$ref": "#/definitions/Group"
              },
              {
                "$ref": "#/definitions/TypedField<string>"
              },
              {
                "$ref": "#/definitions/TypedField<number>"
              },
              {
                "$ref": "#/definitions/TypedField<boolean>"
              }
            ]
          },
          "title": "elements"
        },
        "name": {
          "type": "string",
          "title": "name"
        },
        "controlType": {
          "$ref": "#/definitions/ControlType",
          "title": "controlType"
        },
        "label": {
          "type": "string",
          "title": "label"
        },
        "tooltip": {
          "type": "string",
          "title": "tooltip"
        },
        "dataObjectPath": {
          "description": "A string representing a path to the property in json data file conforming to the plugin schema,\nwhere each path component is seperated by a dot. Same as string representation of\nLodash.get method or mariocasciaro's object-path (https://github.com/mariocasciaro/object-path).\nThis string is unique for all elements in a model and may thus be used as a key if needed.",
          "type": "string",
          "title": "dataObjectPath"
        },
        "required": {
          "type": "boolean",
          "title": "required"
        }
      },
      "additionalProperties": false,
      "required": [
        "kind",
        "elements",
        "name",
        "controlType",
        "label",
        "tooltip",
        "dataObjectPath",
        "required"
      ]
    },
    "TypedField<string>": {
      "title": "TypedField<string>",
      "type": "object",
      "properties": {
        "defaultValue": {
          "type": "string",
          "title": "defaultValue"
        },
        "values": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "title": "values"
        },
        "kind": {
          "type": "string",
          "enum": [
            "field"
          ],
          "title": "kind"
        },
        "type": {
          "$ref": "#/definitions/DataType",
          "title": "type"
        },
        "subType": {
          "$ref": "#/definitions/SubDataType",
          "title": "subType"
        },
        "name": {
          "type": "string",
          "title": "name"
        },
        "controlType": {
          "$ref": "#/definitions/ControlType",
          "title": "controlType"
        },
        "label": {
          "type": "string",
          "title": "label"
        },
        "tooltip": {
          "type": "string",
          "title": "tooltip"
        },
        "dataObjectPath": {
          "description": "A string representing a path to the property in json data file conforming to the plugin schema,\nwhere each path component is seperated by a dot. Same as string representation of\nLodash.get method or mariocasciaro's object-path (https://github.com/mariocasciaro/object-path).\nThis string is unique for all elements in a model and may thus be used as a key if needed.",
          "type": "string",
          "title": "dataObjectPath"
        },
        "required": {
          "type": "boolean",
          "title": "required"
        }
      },
      "additionalProperties": false,
      "required": [
        "defaultValue",
        "kind",
        "type",
        "subType",
        "name",
        "controlType",
        "label",
        "tooltip",
        "dataObjectPath",
        "required"
      ]
    },
    "DataType": {
      "description": "The javascript data types used.",
      "title": "DataType",
      "enum": [
        "boolean",
        "integer",
        "number",
        "string"
      ],
      "type": "string"
    },
    "SubDataType": {
      "title": "SubDataType",
      "enum": [
        "date",
        "date-time",
        "days",
        "email",
        "hostname",
        "hours",
        "ipv4",
        "ipv6",
        "json-pointer",
        "miliseconds",
        "minutes",
        "none",
        "password",
        "port-number",
        "regex",
        "relative-json-pointer",
        "seconds",
        "text",
        "time",
        "uri",
        "uuid"
      ],
      "type": "string"
    },
    "ControlType": {
      "description": "The main gui controls that should be used.",
      "title": "ControlType",
      "enum": [
        "dropdown",
        "group",
        "input",
        "yesno"
      ],
      "type": "string"
    },
    "TypedField<number>": {
      "title": "TypedField<number>",
      "type": "object",
      "properties": {
        "defaultValue": {
          "type": "number",
          "title": "defaultValue"
        },
        "values": {
          "type": "array",
          "items": {
            "type": "number"
          },
          "title": "values"
        },
        "kind": {
          "type": "string",
          "enum": [
            "field"
          ],
          "title": "kind"
        },
        "type": {
          "$ref": "#/definitions/DataType",
          "title": "type"
        },
        "subType": {
          "$ref": "#/definitions/SubDataType",
          "title": "subType"
        },
        "name": {
          "type": "string",
          "title": "name"
        },
        "controlType": {
          "$ref": "#/definitions/ControlType",
          "title": "controlType"
        },
        "label": {
          "type": "string",
          "title": "label"
        },
        "tooltip": {
          "type": "string",
          "title": "tooltip"
        },
        "dataObjectPath": {
          "description": "A string representing a path to the property in json data file conforming to the plugin schema,\nwhere each path component is seperated by a dot. Same as string representation of\nLodash.get method or mariocasciaro's object-path (https://github.com/mariocasciaro/object-path).\nThis string is unique for all elements in a model and may thus be used as a key if needed.",
          "type": "string",
          "title": "dataObjectPath"
        },
        "required": {
          "type": "boolean",
          "title": "required"
        }
      },
      "additionalProperties": false,
      "required": [
        "defaultValue",
        "kind",
        "type",
        "subType",
        "name",
        "controlType",
        "label",
        "tooltip",
        "dataObjectPath",
        "required"
      ]
    },
    "TypedField<boolean>": {
      "title": "TypedField<boolean>",
      "type": "object",
      "properties": {
        "defaultValue": {
          "type": "boolean",
          "title": "defaultValue"
        },
        "values": {
          "type": "array",
          "items": {
            "type": "boolean"
          },
          "title": "values"
        },
        "kind": {
          "type": "string",
          "enum": [
            "field"
          ],
          "title": "kind"
        },
        "type": {
          "$ref": "#/definitions/DataType",
          "title": "type"
        },
        "subType": {
          "$ref": "#/definitions/SubDataType",
          "title": "subType"
        },
        "name": {
          "type": "string",
          "title": "name"
        },
        "controlType": {
          "$ref": "#/definitions/ControlType",
          "title": "controlType"
        },
        "label": {
          "type": "string",
          "title": "label"
        },
        "tooltip": {
          "type": "string",
          "title": "tooltip"
        },
        "dataObjectPath": {
          "description": "A string representing a path to the property in json data file conforming to the plugin schema,\nwhere each path component is seperated by a dot. Same as string representation of\nLodash.get method or mariocasciaro's object-path (https://github.com/mariocasciaro/object-path).\nThis string is unique for all elements in a model and may thus be used as a key if needed.",
          "type": "string",
          "title": "dataObjectPath"
        },
        "required": {
          "type": "boolean",
          "title": "required"
        }
      },
      "additionalProperties": false,
      "required": [
        "defaultValue",
        "kind",
        "type",
        "subType",
        "name",
        "controlType",
        "label",
        "tooltip",
        "dataObjectPath",
        "required"
      ]
    }
  },
  "$schema": "http://json-schema.org/draft-04/schema#"
}

** Example input that should validate but instead gives various errors **

{
    "kind": "group",
    "name": "",
    "controlType": "group",
    "label": "",
    "tooltip": "",
    "dataObjectPath": "",
    "required": true,
    "elements": [
      {
        "kind": "field",
        "name": "username",
        "controlType": "input",
        "label": "User name",
        "tooltip": "a username description here",
        "dataObjectPath": "username",
        "defaultValue": "username default",
        "required": true,
        "type": "string",
        "subType": "none"
      },
      {
        "kind": "field",
        "name": "usertype",
        "controlType": "dropdown",
        "label": "User type",
        "tooltip": "a type description here",
        "dataObjectPath": "usertype",
        "defaultValue": "user",
        "values": [
          "user",
          "superuser"
        ],
        "required": true,
        "type": "string",
        "subType": "none"
      },
      {
        "kind": "field",
        "name": "host",
        "controlType": "input",
        "label": "Hostname",
        "tooltip": "a hostname description here",
        "dataObjectPath": "host",
        "defaultValue": "localhost",
        "required": false,
        "type": "string",
        "subType": "hostname"
      },
      {
        "kind": "field",
        "name": "age",
        "controlType": "input",
        "label": "Age",
        "tooltip": "an age description here",
        "dataObjectPath": "age",
        "defaultValue": 18,
        "required": false,
        "type": "integer",
        "subType": "none"
      },
      {
        "kind": "field",
        "name": "size",
        "controlType": "dropdown",
        "label": "Size",
        "tooltip": "a size description here",
        "dataObjectPath": "size",
        "defaultValue": 0,
        "values": [
          0,
          1,
          2,
          null
        ],
        "required": false,
        "type": "integer",
        "subType": "none"
      },
      {
        "kind": "field",
        "name": "rate",
        "controlType": "input",
        "label": "Rate",
        "tooltip": "a rate description here",
        "dataObjectPath": "rate",
        "defaultValue": 41.42,
        "required": false,
        "type": "number",
        "subType": "none"
      },
      {
        "kind": "field",
        "name": "rank",
        "controlType": "dropdown",
        "label": "Rank",
        "tooltip": "a rank description here",
        "dataObjectPath": "rank",
        "defaultValue": 3.14,
        "values": [
          3.14,
          0.33,
          9.99
        ],
        "required": false,
        "type": "number",
        "subType": "none"
      },
      {
        "kind": "field",
        "name": "registered",
        "controlType": "yesno",
        "label": "Registered",
        "tooltip": "a registered description here",
        "dataObjectPath": "registered",
        "defaultValue": false,
        "required": false,
        "type": "boolean",
        "subType": "none"
      }
    ],
    "errors": []
  }

Functionality in Pull Request 54 has been Overwritten?

This pull request allowed passing in arbitrary keywords that would be accepted and added to the generated schema. This functionality appears to be missing from master now. Am I missing a new way of passing in these kinds of fields (e.g. faker)? Unless I am mistaken, they are now picked up as 'otherAnnotation' and left out of the process

Issue with TypeScript 1.8 dependency when there are .d.ts declarations

When a project contains .d.ts typings, schema generation fails with the error:

/private/tmp/ts/typescript-json-schema/node_modules/typescript/lib/typescript.js:39567
                throw e;
                ^

TypeError: Cannot read property 'replace' of undefined
    at Object.normalizeSlashes (/private/tmp/ts/typescript-json-schema/node_modules/typescript/lib/typescript.js:1383:20)
    at writeReferencePath (/private/tmp/ts/typescript-json-schema/node_modules/typescript/lib/typescript.js:31876:90)
    at /private/tmp/ts/typescript-json-schema/node_modules/typescript/lib/typescript.js:30442:29
    at Object.forEach (/private/tmp/ts/typescript-json-schema/node_modules/typescript/lib/typescript.js:938:30)
    at /private/tmp/ts/typescript-json-schema/node_modules/typescript/lib/typescript.js:30434:20
    at Object.forEach (/private/tmp/ts/typescript-json-schema/node_modules/typescript/lib/typescript.js:938:30)
    at emitDeclarations (/private/tmp/ts/typescript-json-schema/node_modules/typescript/lib/typescript.js:30427:12)
    at getDeclarationDiagnosticsFromFile (/private/tmp/ts/typescript-json-schema/node_modules/typescript/lib/typescript.js:30393:13)
    at onSingleFileEmit (/private/tmp/ts/typescript-json-schema/node_modules/typescript/lib/typescript.js:6380:13)
    at Object.forEachExpectedEmitFile (/private/tmp/ts/typescript-json-schema/node_modules/typescript/lib/typescript.js:6369:21)

The issue seems to be the call to getDeclarationDiagnostics is failing with the error. I don't have enough insight into the typescript compiler, but it looks like a path is not being provided somewhere. The only workaround I can find is to revert the typescript dependency from 1.8.0 to 1.7.5, but someone who knows the typescript transpiler better might have more insight in how to work around it.

Error while trying to generate schema

Any idea why I'm getting this:
λ typescript-json-schema myTSFile.ts MyMainType
npm/node_modules/typescript-json-schema/typescript-json-schema.js:120
else if (propertyType.getSymbol().getName() == "Array") {
^

TypeError: Cannot read property 'getName' of undefined
at JsonSchemaGenerator.getDefinitionForRootType (npm/node_modules/typescript-json-schema/typescript-json-schema.js:120:54)
at JsonSchemaGenerator.getTypeDefinition (npm/node_modules/typescript-json-schema/typescript-json-schema.js:277:29)
at npm/node_modules/typescript-json-schema/typescript-json-schema.js:90:34
at Array.map (native)
at JsonSchemaGenerator.getDefinitionForRootType (npm/node_modules/typescript-json-schema/typescript-json-schema.js:89:45)
at JsonSchemaGenerator.getTypeDefinition (npm/node_modules/typescript-json-schema/typescript-json-schema.js:277:29)
at JsonSchemaGenerator.getDefinitionForProperty (npm/node_modules/typescript-json-schema/typescript-json-schema.js:135:35)
at npm/node_modules/typescript-json-schema/typescript-json-schema.js:237:41
at Array.reduce (native)
at JsonSchemaGenerator.getClassDefinition (npm/node_modules/typescript-json-schema/typescript-json-schema.js:235:49)

Support "anyOf" for union type

Currently union type always output "oneOf", but sometimes a JSON spec might satisfy multiple types of the TS interfaces. Support using "anyOf" instead (and possibly by default would be useful).

I remember @domoritz implemented this with oneOf, not sure how hard it is to use anyOf.

how to force a field to be a specific type?

I am trying to do something like:

/**
* How to force a Widget to be encoded as number?
*
* @type number
*/
export interface Widget {}

export interface House {
    name: string;

    mainWidget: Widget;
    otherWidgets: Widget[];
}

So that the mainWidget field is encoded as a regular "number", and also otherWidgets will be an array of numbers.

In other words I would like to get the following schema:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "properties": {
        "name": {
            "type": "string"
        },
        "mainWidget": {
            "type": "number"
        },
        "otherWidgets": {
            "items": {
                "type": "number"
            },
            "type": "array"
        }
    },
    "required": [
        "name",
        "mainWidget",
        "otherWidgets"
    ],
    "type": "object"
}

thank you

Type comments bugs

Already known issue
Type comments are not used, with union types
#64 (comment)

Type comments are not used, when type is imported from another file

String type, null type and pattern are applied.

/**
 * @pattern \d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}\.\d{3}[+-]\d{4}
 */
export type StringDateNullable = string | null; // "1992-04-10T20:00:00.000+0000"


export interface Person {
    birthDate: StringDateNullable;
}

Only string and null types are applyed, not pattern.

import {
    StringDateNullable
} from './common.types';


export interface Person {
    birthDate: StringDateNullable;
}

Full property info

"birthDate": {
    "pattern": "\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}\\.\\d{3}[+-]\\d{4}",
    "type": [
        "null",
        "string"
    ]
},

Full case

// common.types.ts
/**
 * @pattern \d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}\.\d{3}[+-]\d{4}
 */
export type StringDate = string; // "1992-04-10T20:00:00.000+0000"

// person.types.ts
import {
    StringDate
} from './common.types';


export interface Person {
    birthDate: StringDate | null;
}

Expected result

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "properties": {
        "birthDate": {
            "anyOf": [
                {
                    "pattern": "\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}\\.\\d{3}[+-]\\d{4}",
                    "type": "string"
                },
                {
                    "type": "null"
                }
            ]
        }
    },
    "type": "object"
}

Current result

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "properties": {
        "birthDate": {
            "type": [
                "null",
                "string"
            ]
        }
    },
    "type": "object"
}

Error when generating export interface

Change interface to export interface in test/programs/interface-single/main.ts and you get the error:

09:10 typescript-json-schema$ ./bin/typescript-json-schema test/programs/interface-single/main.ts MyObject

/opt/src/typescript-json-schema/typescript-json-schema.js:314
                throw "type {clazzName} not found";
                ^
type {clazzName} not found

Export interfaces were working with 0.0.6.

License

Any objections against BSD?

Is there a way to export all interfaces in a file?

Hi,

I am looking for way to get all interfaces from one file. So far referenced all interfaces in that file in a interface that I exported so get all the interfaces, but that's ugly and error prone..
I also tried to use '*' wildcard when calling the cli but that does not work at all.

Any idea on how to accomplish it in a nice way?

Better examples & documentation

  • document TJS-* properties which can be set via comments
  • document advanced examples
  • explain + demo some use cases to demonstrate value

Preserve type aliases in the `definitions` block

Hi. Thank you for the great tool!

Could you please check this example?

  1. Here's my TS file

    namespace Test.Common {
        export interface EmptyObject {}
        export type DateTime = string;
    }
    
    namespace Test.Data {
        import EmptyObject = Test.Common.EmptyObject;
        import DateTime = Test.Common.DateTime;
    
        export interface Result {
            emptyObject: EmptyObject;
            dateTime: DateTime;
        }
    }
  2. command line:

    ./node_modules/.bin/typescript-json-schema test.ts Test.Data.Result --refs --aliasRefs
  3. and the result:

    {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "definitions": {
            "Test.Common.EmptyObject": {
                "properties": {
                },
                "type": "object"
            },
            "string": {
                "type": "string"
            }
        },
        "properties": {
            "dateTime": {
                "$ref": "#/definitions/string"
            },
            "emptyObject": {
                "$ref": "#/definitions/Test.Common.EmptyObject"
            }
        },
        "type": "object"
    }

As you may see, the Test.Common.DateTime name is replaced by string in the definition name, but the Test.Common.EmptyObject import isn't.

Is it possible to preserve names for type aliases? I'd like to have something like this:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "definitions": {
        "Test.Common.EmptyObject": {
            "properties": {
            },
            "type": "object"
        },
        "Test.Common.DateTime": {
            "type": "string"
        }
    },
    "properties": {
        "dateTime": {
            "$ref": "#/definitions/Test.Common.DateTime"
        },
        "emptyObject": {
            "$ref": "#/definitions/Test.Common.EmptyObject"
        }
    },
    "type": "object"
}

Avoid infinite loops

With references we should be able to support interfaces that reference themselves, The easiest fix would be to only recurse if the type does not yet exist in the map of definitions.

Unnecessary \n

interface Test {
    /**
     * Classification level from 1 to 5 (highest)
     * @type integer
     * @default 12
     */
    level: number;
}

generates

{
    "type": "object",
    "title": "Category",
    "defaultProperties": [],
    "properties": {
        "level": {
            "type": "integer\n\n",
            "title": "level",
            "description": "Classification level from 1 to 5 (highest)",
            "default": 12
        }
    }
}

If the type is "any" no definition is printed

export interface IResultResponse {
    success:boolean;
    message?:string;
    data?:any;
}

turns into

IResultResponse:
  type: object
  properties:
    success:
      type: boolean
    message:
      type: string
    data:
  additionalProperties: false
  required:
    - success

interface definition does not generate 'required' property in json-schema

With typson, properties of an interface are serialized as 'required' unless they are marked optional.

Given an interface like:

interface Foo {
   bar? : number
   baz: string 
}

In the resulting json-schema, I'd expect baz to be marked required and bar not. This is based on my previous experiments with typson. That said, toggling this behavior via a config setting or command line parameter would be nice.

It seems like this implementation is significantly different from typson and I maybe shouldn't assume it's a superset of typson?

CLI tool not work

/usr/bin/typescript-json-schema: line 1: #!/usr/bin/env: No such file or directory
/usr/bin/typescript-json-schema: line 2: syntax error near unexpected token `$'{\r''
/usr/bin/typescript-json-schema: line 2: `if (process.argv[2] !== undefined && process.a'gv[3] !== undefined) {

Improper `Date` type schema generation

When generating schema for interface with property of type Date as the output we get additional Date which is typescript Date type interface:

{
 "Date": {
            "type": "object",
            "properties": {
                "toString": {
                    "$ref": "#/definitions/() => string",
                    "description": "Returns a string representation of a date. The format of the string depends on the locale."
                },
                "toDateString": {
                    "$ref": "#/definitions/() => string",
                    "description": "Returns a date as a string value."
                },
                "toTimeString": {
                    "$ref": "#/definitions/() => string",
                    "description": "Returns a time as a string value."
                },
                "toLocaleString": {
                    "$ref": "#/definitions/{ (): string; (locales?: string[], options?: DateTimeFormatOptions): string; (locale?: string, op...",
                    "description": "Returns a value as a string value appropriate to the host environment's current locale.\n\nConverts a date and time to a string by using the current or specified locale.\n\nConverts a date and time to a string by using the current or specified locale."
                },
                "toLocaleDateString": {
                    "$ref": "#/definitions/{ (): string; (locales?: string[], options?: DateTimeFormatOptions): string; (locale?: string, op...",
                    "description": "Returns a date as a string value appropriate to the host environment's current locale.\n\nConverts a date to a string by using the current or specified locale.\n\nConverts a date to a string by using the current or specified locale."
                },
                "toLocaleTimeString": {
                    "$ref": "#/definitions/{ (): string; (locale?: string[], options?: DateTimeFormatOptions): string; (locale?: string, opt...",
                    "description": "Returns a time as a string value appropriate to the host environment's current locale.\n\nConverts a time to a string by using the current or specified locale.\n\nConverts a time to a string by using the current or specified locale."
                },
                "valueOf": {
                    "$ref": "#/definitions/() => number",
                    "description": "Returns the stored time value in milliseconds since midnight, January 1, 1970 UTC."
                },
                "getTime": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the time value in milliseconds."
                },
                "getFullYear": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the year, using local time."
                },
                "getUTCFullYear": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the year using Universal Coordinated Time (UTC)."
                },
                "getMonth": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the month, using local time."
                },
                "getUTCMonth": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the month of a Date object using Universal Coordinated Time (UTC)."
                },
                "getDate": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the day-of-the-month, using local time."
                },
                "getUTCDate": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the day-of-the-month, using Universal Coordinated Time (UTC)."
                },
                "getDay": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the day of the week, using local time."
                },
                "getUTCDay": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the day of the week using Universal Coordinated Time (UTC)."
                },
                "getHours": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the hours in a date, using local time."
                },
                "getUTCHours": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the hours value in a Date object using Universal Coordinated Time (UTC)."
                },
                "getMinutes": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the minutes of a Date object, using local time."
                },
                "getUTCMinutes": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the minutes of a Date object using Universal Coordinated Time (UTC)."
                },
                "getSeconds": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the seconds of a Date object, using local time."
                },
                "getUTCSeconds": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the seconds of a Date object using Universal Coordinated Time (UTC)."
                },
                "getMilliseconds": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the milliseconds of a Date, using local time."
                },
                "getUTCMilliseconds": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the milliseconds of a Date object using Universal Coordinated Time (UTC)."
                },
                "getTimezoneOffset": {
                    "$ref": "#/definitions/() => number",
                    "description": "Gets the difference in minutes between the time on the local computer and Universal Coordinated Time (UTC)."
                },
                "setTime": {
                    "$ref": "#/definitions/(time: number) => number",
                    "description": "Sets the date and time value in the Date object."
                },
                "setMilliseconds": {
                    "$ref": "#/definitions/(ms: number) => number",
                    "description": "Sets the milliseconds value in the Date object using local time."
                },
                "setUTCMilliseconds": {
                    "$ref": "#/definitions/(ms: number) => number",
                    "description": "Sets the milliseconds value in the Date object using Universal Coordinated Time (UTC)."
                },
                "setSeconds": {
                    "$ref": "#/definitions/(sec: number, ms?: number) => number",
                    "description": "Sets the seconds value in the Date object using local time."
                },
                "setUTCSeconds": {
                    "$ref": "#/definitions/(sec: number, ms?: number) => number",
                    "description": "Sets the seconds value in the Date object using Universal Coordinated Time (UTC)."
                },
                "setMinutes": {
                    "$ref": "#/definitions/(min: number, sec?: number, ms?: number) => number",
                    "description": "Sets the minutes value in the Date object using local time."
                },
                "setUTCMinutes": {
                    "$ref": "#/definitions/(min: number, sec?: number, ms?: number) => number",
                    "description": "Sets the minutes value in the Date object using Universal Coordinated Time (UTC)."
                },
                "setHours": {
                    "$ref": "#/definitions/(hours: number, min?: number, sec?: number, ms?: number) => number",
                    "description": "Sets the hour value in the Date object using local time."
                },
                "setUTCHours": {
                    "$ref": "#/definitions/(hours: number, min?: number, sec?: number, ms?: number) => number",
                    "description": "Sets the hours value in the Date object using Universal Coordinated Time (UTC)."
                },
                "setDate": {
                    "$ref": "#/definitions/(date: number) => number",
                    "description": "Sets the numeric day-of-the-month value of the Date object using local time."
                },
                "setUTCDate": {
                    "$ref": "#/definitions/(date: number) => number",
                    "description": "Sets the numeric day of the month in the Date object using Universal Coordinated Time (UTC)."
                },
                "setMonth": {
                    "$ref": "#/definitions/(month: number, date?: number) => number",
                    "description": "Sets the month value in the Date object using local time."
                },
                "setUTCMonth": {
                    "$ref": "#/definitions/(month: number, date?: number) => number",
                    "description": "Sets the month value in the Date object using Universal Coordinated Time (UTC)."
                },
                "setFullYear": {
                    "$ref": "#/definitions/(year: number, month?: number, date?: number) => number",
                    "description": "Sets the year of the Date object using local time."
                },
                "setUTCFullYear": {
                    "$ref": "#/definitions/(year: number, month?: number, date?: number) => number",
                    "description": "Sets the year value in the Date object using Universal Coordinated Time (UTC)."
                },
                "toUTCString": {
                    "$ref": "#/definitions/() => string",
                    "description": "Returns a date converted to a string using Universal Coordinated Time (UTC)."
                },
                "toISOString": {
                    "$ref": "#/definitions/() => string",
                    "description": "Returns a date as a string value in ISO format."
                },
                "toJSON": {
                    "$ref": "#/definitions/(key?: any) => string",
                    "description": "Used by the JSON.stringify method to enable the transformation of an object's data for JavaScript Object Notation (JSON) serialization."
                }
            }
        },
        "() => string": {
            "type": "object",
            "properties": {}
        },
        "{ (): string; (locales?: string[], options?: DateTimeFormatOptions): string; (locale?: string, op...": {
            "type": "object",
            "properties": {}
        },
        "{ (): string; (locale?: string[], options?: DateTimeFormatOptions): string; (locale?: string, opt...": {
            "type": "object",
            "properties": {}
        },
        "() => number": {
            "type": "object",
            "properties": {}
        },
        "(time: number) => number": {
            "type": "object",
            "properties": {}
        },
        "(ms: number) => number": {
            "type": "object",
            "properties": {}
        },
        "(sec: number, ms?: number) => number": {
            "type": "object",
            "properties": {}
        },
        "(min: number, sec?: number, ms?: number) => number": {
            "type": "object",
            "properties": {}
        },
        "(hours: number, min?: number, sec?: number, ms?: number) => number": {
            "type": "object",
            "properties": {}
        },
        "(date: number) => number": {
            "type": "object",
            "properties": {}
        },
        "(month: number, date?: number) => number": {
            "type": "object",
            "properties": {}
        },
        "(year: number, month?: number, date?: number) => number": {
            "type": "object",
            "properties": {}
        },
        "(key?: any) => string": {
            "type": "object",
            "properties": {}
        }
}

but IMHO it should fall back to

{
   "type": "string",
   "format": "date-time",
}

Accessing the JsonSchemaGenerator class

Hey guys,

I'm working with a custom version of the typescript compiler and was hoping to generate schema for certain types - but not all. I already have access to the ts.Type I want a schema for and I used JsonSchemaGenerator.getSchemaForSymbols to get it but I had to modify your code to export the JsonSchemaGenerator class.

Do you see something inherently wrong with this approach ? If not, would you welcome a pull request changing the TJS module to export the JsonSchemaGenerator class so it can be accessed from the outside ?

Question: json-schema to typescript or typescript to json-jschema

Hi,

I'm new to typescript and json-schema and I would like to know which one is the more complete. I want to use the most complete one as base in order to generate the other one. At first glance I would think json-schema is more complete and polyvalent than typescript.

Could someone confirm this?

An idea: it would be great to be able to be bidirectionnal.

Thanks for your response and for your work on this project.

Top-level type annotations.

Given the file ./dimension.ts

/**
 Some dimension 
 @additionalProperties false
*/
interface Dimension {
    /**  Width in cm */
        width: number;

    /** Height in cm */
        height: number;

    /** Length in cm */
        length:  number;
}

we observe this output:

$ typescript-json-schema dimension.ts Dimension
{
    "type": "object",
    "properties": {
        "width": {
            "type": "number",
            "description": "Width in cm"
        },
        "height": {
            "type": "number",
            "description": "Height in cm"
        },
        "length": {
            "type": "number",
            "description": "Length in cm"
        }
    },
    "$schema": "http://json-schema.org/draft-04/schema#"
}

Do we expect the top-level type to include a description (and additionalProperties) attribute?

typson output:

$ typson schema ./dimension.ts
{
  "Dimension": {
    "id": "Dimension",
    "type": "object",
    "description": "Some dimension",
    "additionalProperties": false,
    "properties": {
      "width": {
        "description": "Width in cm",
        "type": "number"
      },
      "height": {
        "description": "Height in cm",
        "type": "number"
      },
      "length": {
        "description": "Length in cm",
        "type": "number"
      }
    },
    "required": [
      "width",
      "height",
      "length"
    ]
  }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.