Precision loss when handling large `integer`
JSON allows for infinite precision, so it's valid to represent uint64 with the following
{
"maximum": 18446744073709551615,
"minimum": 0,
"type": "integer"
}
Note: integer here is used instead of number to represent the fact it's not a floating point number
However, 18446744073709551615 cannot be represented as a Javascript number (it will instead get converted to 18446744073709552000)
However, this is hard to solve in this library...
Problem 1) JSON.parse
JSON.parse itself is lossy. In face, parsing bigint is not even something you can do with JSON.parse's custom resolver, so you need a custom library to achieve this
Fortunately, there are a few libraries that can help with this (ex: something like lossless-json that can handle both arbitrary precision numbers and integers) so this error can be surmounted (although annoying)
Problem 2) json-schema
Unfortunately, json-schema (and transitively @apidevtools/json-schema-ref-parser) uses number has the Javascript type for fields like exclusiveMaximum, so even if you use a proper replacement for JSON.parse yourself, these other libraries won't and don't have the proper type definitions for a replacement
I created a Github issues to track this:
-
@apidevtools/json-schema-ref-parser: https://github.com/APIDevTools/json-schema-ref-parser/issues/379
Problem 3) @sinclair/typebox
Even if you somehow surmount problems (1) and (2), you have another problem: typebox itself only allows number types in Type.Number(). If you want to solve this, you instead have to use Type.BigInt (a custom Typebox-specific type that supports bigint types). However, when serialized, Type.BigInt doesn't result in "type": "integer", but rather "type": "bigint". This can maybe be patched around by using custom (de)serializers with Type.Transform and Type.Unsafe, but this is tricky
This limitation is maybe less important, since I think this library is more about going from json schema → typebox, and it's less important that the generated code gives you back exactly the same starting schema if you go from typebox → json schema
I created a Github issue to track this:
- https://github.com/sinclairzx81/typebox/issues/280#issuecomment-2795859327
Summary
Given every part of the stack struggles with supporting numbers larger than JS max precision, I don't think it's unreasonable to just leave this issue open as a warning to others who use this library about this limitation. I created this issue more to document the various blockers in case somebody wants to try tackling this in the future (although the complexity may not be worth ever tackling this)