npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

jsonschema-to-typings

v0.2.14

Published

A command-line utility and module to turn a JSON Schema into a typescript interface definition

Downloads

120

Readme

jsonschema-to-typings

NPM version

Npm Downloads

A command-line utility and module to turn a JSON Schema into a typescript interface definition

I wrote this module because I have a set of REST based backends using JSON Schema for their input and output validation. I wanted to expose this information to clients written in TypeScript and add code hinting/completion during development. There are certain things that JSON Schema can do that TypeScript can't and visa versa. With this module you've at least got an automated starting point for converting a large set of schemas.

DISCLAIMER: I wrote this module to fit my specific project needs. The schemas I work with are very much bound by id's and live within their own eco-system. I'm not covering the whole JSON Schema specification nor do I fully intend to. Feel free to fork or file pull requests as you see fit with this in mind.

UPDATE: I have released version 0.2.0 which changes the following:

  • No more top level module name
  • Using 'export interface ...' for all outputed interfaces
  • Using preferred simple array notation 'string[]' instead of 'Array<string>'

I bumped the minor version because this is a pretty structural change in the output format

Command-line usage

At the very least you need to supply one schema and the name of the output module:

jsonschema2typings -m MyModule schemas/*.json

Calling with -h will provide you with all the possible options:

  Usage: jsonschema2typings [options] <file...>

  Options:

    -h, --help                  output usage information
    -V, --version               output the version number
    -p, --prefix [prefix]       Interface prefix. Default: 'I'
    -tp, --type-prefix [prefix] Type prefix. Default: 'T'
    --enum-prefix [prefix]      Enum prefix. Default: 'E'
    --enum-type [type]          Type of enum to generate: 'type', 'enum' or 'string-enum. Default: type
    -o, --out [file]            Output TypeScript file. Default output is to STDOUT
    -nsl, --no-string-literals  Don not use TypeScript 1.8 string literals for enums
    -d, --path-depth            The number of id/path elements to use for name resolution. Default: 1
    -v, --verbose               Enable debug output

Code usage

You can use the schema converter module as follows:

var converter = require( "jsonschema-to-typings" );

var mySchemas = [
    require( "schema1.json" ),
    require( "schema2.json" ),
    ...
];

var typescriptCode = converter( mySchemas,
{
    "noStringLiterals": false
,   "debug":            false
,   "prefix":           "I"
,   "typePrefix":       "T"
,   "enumPrefix":       "E"
,   "enumType":         "string-enum"
,   "pathDepth":        1
} );

String literals

TypeScript has added support for string literal types since version 1.8. These are really nice to use for string based enumerations. If you're working with an older version of typescript you can disable this feature and your properties will revert to a normal string.

Encountering a string/enum type in JSON Schema will add a type to your module like this:

type TMyEnum = "MyValue1" | "MyValue2";

interface IExample {
    myStringEnum: TMyEnum;
}

Enums

This tool predates the proper support for string enums so the default is to generate enums as a Type. You van now use the new

Schema name deduction

The name for a schema is deduced from it's id. The last path element is extracted and camel-cased. You can set the path depth to use using the path-depth/pathDepth option both in code and command-line. You can provide your own name extraction function using the nameMapping option but this option is not available on the command-line.

The name mapping function is called with 2 parameters:

function( id: string, pathDepth: number ): string
{
    ...
    return "name";
}

The pathDepth contains the configured path depth option which you are free to ignore. Just ensure the function returns a unique name for your interface and/or type.

Example

The following JSON Schema:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "https://github.com/Qwerios/jsonschema-to-typings/test/geo.json",
    "properties": {
        "elevation": {
            "description": "The elevation of the geo-coordinates",
            "id": "https://github.com/Qwerios/jsonschema-to-typings/test/geo.json/elevation",
            "type": "number"
        },
        "latitude": {
            "description": "The latitude of the geo-coordinates",
            "id": "https://github.com/Qwerios/jsonschema-to-typings/test/geo.json/latitude",
            "type": "number"
        },
        "longitude": {
            "description": "The longitude of the geo-coordinates",
            "id": "https://github.com/Qwerios/jsonschema-to-typings/test/geo.json/longitude",
            "type": "number"
        }
    },
    "required": [
        "latitude",
        "longitude"
    ],
    "type": "object"
}

Would look like this as a typescript declaration:

export interface IGeo {
    elevation?: number;
    latitude: number;
    longitude: number;
}

Known limitations

Default type

If type is omitted in a JSON schema property object is assumed. This will lead to an any type property in TypeScript.

Arrays

JSON Schema allows arrays to define that they can only contain unique items and what the minimum and maximum item counts are. TypeScript interfaces only allow us to declare the Array and it's containing type. End result is that the extra validation requirements from the JSON Schema are lost

Formatters

Formatter are a runtime option for JSON Schema validators. TypeScript declarations are just static type checks at compile time. As such the default formatters and custom formatters can not be enforced or declared.

Null type

JSON Schema has a null type but in TypeScript any type is nullable. I opted to default to number for these properties because any felt too open ended.

Nesting objects

We can nest objects in JSON Schema without naming them. In TypeScript interfaces we only have one level of object interfaces unless we refer to another interface by name. If you find yourself nesting objects a lot in JSON Schema consider moving them to their own schema and linking them via $ref. It might be possible to generate on-demand interfaces but the readability of the output will suffer so I opted not to. I've always found it better to keep my JSON Schema's shallow, focussed and reusable.