5 ms·
Is there something wrong with just using TypeScript's type system for expressing the required format of JSON data that would make me want to use the significant
by peterkelly 9y ago
Is there something wrong with just using TypeScript's type system for expressing the required format of JSON data that would make me want to use the significantly more verbose JSON schema format instead? I've written a couple of code generators (e.g. [1]) in the past which use the former approach and found it a very convenient way to express my models.
For example this:
{
"title": "Person",
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"age": {
"description": "Age in years",
"type": "integer",
"minimum": 0
}
},
"required": ["firstName", "lastName"]
}
can be expressed like this:
interface Person {
firstName: string;
lastName: string;
age?: number; // Age in years
}
I can see that there are additional constraints expressible, such as the fact that age has to be an integer and has a minimum value. However those could all conceivably comprise a superset of TypeScript's interface definitions. JSON Schema just feels to me like XML Schema all over again.
[1] https://www.npmjs.com/package/jsonidator https://www.npmjs.com/package/jsonidator
- lucian1900 9y agoIt is considered essential that JSON schema is expressible as JSON. There are advantages to that, but it could be only a wire representation instead, with some more concise syntax alternative.
- peterkelly 9y ago> It is considered essential that JSON schema is expressible as JSON Why? It's not a particularly difficult task to write a parser that could convert between the two representations. The TypeScript compiler even provides an API that lets you access its AST.
- deleted 9y ago[deleted]
- antjanus 9y agoWell, here's the thing, you can write a parser to translate that TS into JSON schema format and that works. At my job, we're currently running JS on the back-end and TS on the front-end. JSON-Schema can be used in both. We're also rebuilding our core functionality in Elixir, and guess what, JSON Schema works there, too, out of the box.
- atmartins 9y agoJSON schema can be the representation used to exchange information between two or more systems, languages, projects, etc. It's a form of lowest common denominator, something that can (somewhat) fully describe your interface but in a static, commonly available, easily parsed, easily generated way.
- thangngoc89 9y agoBecause json-schema is language agnostic. You can have a schema that can be shared between servers/clients with different languages. If you want to do it the TypeScript way, then you can generate the types from json-schema (probably via an automated tool)
- legulere 9y agojson is also based on javascript, but language agnostic. You could also specify a subset of typescript, just like json is a subset of javascript.
- jupp0r 9y agoThere is nothing wrong with Typescript definitions if that works for your use case. Json schema is more flexible: - it can do checks at runtime (to validate untrusted input, for example) - there are libraries for many other programming languages - it can express constraints on values as well as on types (size of arrays, string regex matching, integer value ranges, ...)
- domoritz 9y agoI built a tool to generate JSON Schema from typescript interfaces: https://www.npmjs.com/package/ts-json-schema-generator https://www.npmjs.com/package/ts-json-schema-generator The reason for having the schema are that they are language agnostic and there is wide tool support. For example, vscode supports autocomplete and tooltips when you use json schema.
- kbenson 9y agoSo, in typescript a number is unsigned by default? If not, your typescript representation has lost some information compared to the JSON schema example, and would theoretically allow for negative ages. Additionally, what you've chosen is a very simple example, and even in that case you're having trouble correctly mapping the types to what is expected. What about a slightly more complex one[1]? { "$schema": "http://json-schema.org/draft-06/schema#", "type": "object", "properties": { "/": {} }, "patternProperties": { "^(/[^/]+)+$": {} }, "additionalProperties": false, "required": [ "/" ] } 1: http://json-schema.org/example2.html
- skrebbel 9y agoNo, there's nothing wrong with that and it's usually significantly more readable than JSON Schema. Good idea! Of course there are use cases that JSON Schema works better for (eg most other replies you got) but I fully agree that TypeScript type definitions are a great way to specify the structure of JSON data. To make it feel more language-agnostic, you could consider using type aliases instead: type Person = { firstName: string, lastName: string, age?: number // Age in years } This is equivalent to the interface you described, but potentially less confusing to readers who don't know what an "interface" is (eg because they mostly used Ruby or C++). You don't even need to tell people that it's TypeScript - this could be a perfectly sensible schema language for JSON. A bit like what RELAX NG[0] is for XML. At my company we actually use typescript-json-schema[1] so we can specify the structure of our API payloads in TS instead of JSON Schema and still benefit from JSON Schema's better tool support. [0] https://en.wikipedia.org/wiki/RELAX_NG#Compact_syntax https://en.wikipedia.org/wiki/RELAX_NG#Compact_syntax [1] https://github.com/YousefED/typescript-json-schema https://github.com/YousefED/typescript-json-schema
- HumanDrivenDev 9y agoAFAIK typescript interfaces don't exist at runtime, so you can't validate incoming JSON with type any. Also you can't really hand a third party a typescript interface and tell them to conform with that. And finally, I would imagine a good schema could enforce more things like the length of identifiers, whether a number can be negative, etc.
- zbentley 9y ago> AFAIK typescript interfaces don't exist at runtime, so you can't validate incoming JSON with type any. That's mostly true, but some projects exist that allow a subset of interfaces to be used at runtime: - https://github.com/gcanti/io-ts https://github.com/gcanti/io-ts - https://github.com/fabiandev/ts-runtime https://github.com/fabiandev/ts-runtime - https://github.com/codemix/flow-runtime https://github.com/codemix/flow-runtime - Or just manual assertions: https://gist.github.com/JohnWeisz/beb7b4dadc512be30ce6c7c1e4c7e652 https://gist.github.com/JohnWeisz/beb7b4dadc512be30ce6c7c1e4...
- zbentley 9y agoTypeScript provides, primarily, a type verification system. JSON-schema provides a type assertion system. Both serve as type documentation systems. TS says "if you create objects in my world, I will use my type system to verify that you're creating the right kind of objects, and you can look up their definitions to see what's in them". JSON-schema says "if you give me external, un-annotated objects, I can tell you whether they comply with a type definition, and you can look at that definition to see what's in them". TS has a limited assertion facility, but it's not nearly as capable as JSON-schema. Projects like io-ts (https://github.com/gcanti/io-ts https://github.com/gcanti/io-ts) add more functionality to those assertions, but they're still much less easy to use, in my opinion, than JSON-schema for this purpose. If you're using TS types to assert, though, you can definitely describe more complex constraints, so it may make sense as an alternative to JSON-schema for some people. As others have pointed out, JSON-schema is also much easier to use on non-TypeScript platforms than TS assertions, which, even if you use an assertion library like io-ts, will still be limited in use to JavaScript (and JS-to-$other_language runtimes).
- CMCDragonkai 9y agoA dependent type system can do both.
- zbentley 9y ago...yes it can? Would you expand on how dependent type systems are relevant to the differences between TypeScript/JSON-Schema, or how the use of a DTS could help ameliorate the issues people have in those areas?
- CMCDragonkai 9y agoNot in an HN comment, but here's a paper called Power of Pi https://cs.ru.nl/~wouters/Publications/ThePowerOfPi.pdf https://cs.ru.nl/~wouters/Publications/ThePowerOfPi.pdf that probably explains it the best. It shows the usage of it for deriving a parser and generator from a single specification, and also crypto protocols and database usage. It uses Agda for its examples, but it can be translated to Idris as well.