glideapps / quicktype

Generate types and converters from JSON, Schema, and GraphQL
https://app.quicktype.io
Apache License 2.0
12.35k stars 1.07k forks source link

Schema generation fails silently with TypeScript 3 #1034

Closed jlfwong closed 6 years ago

jlfwong commented 6 years ago

When I upgraded a project to TypeScript 3, schema generation started silently failing.

Repro:

$ git clone https://github.com/jlfwong/quicktype-typescript-3-bug.git
$ npm install
$ npm ls -depth 0
quicktype-typescript-3-bug@1.0.0 /Users/jlfwong/code/quicktype-typescript-3-bug
├── quicktype@15.0.105
└── typescript@3.0.1
$ cat test.ts
interface Foo { x: 1 }
$ node_modules/.bin/quicktype -l schema test.ts
{
    "$schema": "http://json-schema.org/draft-06/schema#",
    "definitions": {}
}

If I downgrade to TypeScript 2.8, it works correctly:

$ npm ls -depth 0
quicktype-typescript-3-bug@1.0.0 /Users/jlfwong/code/quicktype-typescript-3-bug
├── quicktype@15.0.105
└── typescript@2.8.1
$ node_modules/.bin/quicktype -l schema test.ts
{
    "$schema": "http://json-schema.org/draft-06/schema#",
    "definitions": {
        "Foo": {
            "title": "Foo",
            "type": "object",
            "properties": {
                "x": {
                    "type": "number",
                    "enum": [
                        1
                    ],
                    "title": "x"
                }
            },
            "required": [
                "x"
            ]
        }
    }
}

I'm guessing that quicktype hasn't gotten around to TypeScript 3 support yet, which is totally understandable given that it was very recently released! It would've saved me a lot of trouble, however, if it failed loudly rather than silently.

schani commented 6 years ago

@jlfwong That only happens with TypeScript input?

jlfwong commented 6 years ago

@schani I haven't tested anything else. My suspicion is that it's typescript specific because the problem goes away when downgrading from typescript 3 to 2.8, as described in the issue description.

jlfwong commented 6 years ago

This also fails for typescript@2.9.2

schani commented 6 years ago

Fixed in #1037

jlfwong commented 6 years ago

Thanks! Will the next release work for both typescript@2.x.x or only for typescript@3.x.x?

schani commented 6 years ago

For Typescript input, unlikely. We're depending on typescript itself, in particular 3.x, so you'll probably run into weird dependency issues.

jlfwong commented 6 years ago

@schani I'm a bit confused -- if quicktype is depending upon typescript itself, then why does the version of typescript present in the project depending upon quicktype affect whether it outputs correctly? The parsing grammar of typescript 3 should be roughly a superset of typescript 2, so I'd expect that always using the typescript 3 parser should work, even for typescript 2.

Independent of that question, is it possible to make it fail loudly rather than silently? I found it really surprising that when it failed to parse it generated an empty schema rather than crashing with a helpful error message.

schani commented 6 years ago

quicktype uses the typescript package for two different purposes:

  1. at compile-time, to compile itself
  2. at run-time, to parse TypeScript input (indirectly via the typescript-json-schema package)

The API of typescript, the compiler, changed between 2 and 3, and typescript-json-schema was updated for 3. My guess is that it won't work if you feed it the 2 compiler. This has nothing to do with the grammar of TypeScript, but with the API of the compiler.

What's the reason you need it work with both 2 and 3?

jlfwong commented 6 years ago
  1. at run-time, to parse TypeScript input (indirectly via the typescript-json-schema package)

I guess my question is why is this portion affected by what version of the typescript compiler is in the project that consumes quicktype? I would assume that the version of the compiler used to parse would be just whatever is defined by typescript-json-schema's package.json.

npm supports having multiple versions of the same package in the dependency tree, so I would expect that independent of what version of the typescript compiler I'm using in my project, that typescript-json-schema could use the typescript 3 compiler.

What's the reason you need it work with both 2 and 3?

I don't personally have this need at the moment, but when I discovered this bug, I downgraded from TypeScript 3 to 2.8 to fix the problem. If I now pull the latest version of quicktype, it will begin failing unless I also re-upgrade to TypeScript 3, and it seems like it should be possible to support both by unconditionally using the TypeScript 3 compiler API rather than depending upon whatever is in the consumer's package.json.

I believe that means that anyone that's currently using quicktype without locking to the specific patch version that has typescript@2.x.x in their project will suddenly have schema compilation crash.

I verified this in the test repository in the start of this repo:

$ quicktype-typescript-3-bug@1.0.0 /Users/jlfwong/code/quicktype-typescript-3-bug
├── quicktype@15.0.107
└── typescript@2.8.1
Error: program.getConfigFileParsingDiagnostics is not a function.

This at least is not a silent failure, which I think is progress! But it's unfortunate that a patch version bump breaks some people's quicktype installation.

So I believe this was accidentally a breaking major version change somewhere between quicktype@15.0.105 and quicktype@15.0.107.

schani commented 6 years ago

The quicktype package is not meant to be used as a library - quicktype-core and quicktype-typescript-input (and quicktype-graphql-input) are, see here for how to do this. So it's definitely not a breaking change in quicktype, maybe it is in quicktype-typescript-input.

If you know how to modify quicktype-typescript-input such that it independently depends on typescript 3, please send us a PR.

jlfwong commented 6 years ago

The quicktype package is not meant to be used as a library

FWIW, I'm not using it as a library, I'm using it as a dependency in order to use its command-line interface as part of build scripts.

In any case, thank you for the quick responses and explanations! quicktype has generally be very helpful both for helping me specify the file format for speedscope in a language agnostic way, and for generating rust bindings to that file format for integration into a rust project. Thank you for all the work you've done on it!

schani commented 6 years ago

Cheers!

Sorry I can't help you here :-(