-
Notifications
You must be signed in to change notification settings - Fork 162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support BigInt #280
Comments
@sachinraja Hi, thanks for the suggestion. At this stage, There are two main things preventing it's inclusion of The first is that BigInt cannot be expressed in JSON. Currently the The second is BigInt constraints cannot be expressed in JSON. For example, the I'll leave this issue open for a while and give it a little bit of thought. |
Thanks for the quick response! Perhaps there should be a way of defining certain schema types only for use with the type compiler. I'm not sure what the added complexity of that would be though. |
@sachinraja Hi, just had a quick look various support for bigint this morning, and unfortunately, the data type doesn't appear to be supported in msgpack. It also doesn't seem to be configurable Ajv either (even through custom types) MsgPackimport { encode, decode } from 'npm:@msgpack/msgpack'
encode({ value: 1000n }) // having this work would be the minimum barrier to entry. Error
There does however appear to be an upstream PR in msgpack to support BigInt here msgpack/msgpack-javascript#211, so it would be worth revisiting AjvI can't seem to configure Ajv for custom types (which is pretty awkward). The following would be the unsafe type for BigInt. function schemaOf(schemaOf: string, value: unknown, schema: any) {
// this logic never gets run as ajv seems to ignore the numeric bigint values
if(schema[Kind] === 'BigInt') {
return typeof value === 'bigint'
} else {
return false
}
}
const ajv = new Ajv({}).addKeyword({ type: 'integer', keyword: 'typeOf', validate: schemaOf })
const BigInt = () => Type.Unsafe<bigint>({
[Kind]: 'BigInt',
type: 'integer',
typeOf: 'BigInt'
})
const R = ajv.validate(Type.Object({
value: BigInt(),
}), {
value: 1000, // Ajv ignores bigints
})
console.log(R) There does appear to be a open issue to support BigInt under the Metadata PublishingI think the inability to serialize type information for bigint is probably going to be the main blocker for adding BigInt to TypeBox. Ideally, it should be possible to do the following (where the serialized schema may be published to remote consumers) const T = Type.Object({
value: Type.BigInt({ minimum: 0n, maximum: 1000n })
})
const S = JSON.stringify(T) // error: Uncaught TypeError: Do not know how to serialize a BigInt
// const S = {
// type: 'object',
// required: ['value'],
// properties: {
// value: { type: 'integer', typeOf: 'BigInt', minimum: 0n, maximum: 1000n }
// } ^ error ^ error
// } The problem here is that the SummaryI think given some of the technical limitations in I might need to defer BigInt for the time being and just keep an eye on upstream functionality being added elsewhere first. Ill track this issue with the label |
@sachinraja Just as a follow up, I think the fastest path to getting BigInt supported in TypeBox would probably be to provide custom schema support in the compiler (which is still pending). Currently TypeBox provides support for custom string formats, but I think a similar mechanism could be developed for complete custom schemas (which would enable the ability for end users to create BigInt as a custom type) Linking Reference Issue #244 |
@sachinraja Hiya. Have just updated TypeBox to support Custom types. It's now possible to support non JSON Schema types (such as bigint) by registering the types Documentation for Custom Types can be found here BigInt implementation below. import { Type, Kind } from '@sinclair/typebox'
import { Custom } from '@sinclair/typebox/custom'
import { TypeCompiler } from '@sinclair/typebox/compiler'
// Register Type with the Custom namespace
Custom.Set('BigInt', value => typeof value === 'bigint')
// Create a Type schema using the [Kind] property
const T = Type.Unsafe<bigint>({ [Kind]: 'BigInt' })
// Compile it
const C = TypeCompiler.Compile(T)
// Check it
console.log(C.Check(100n)) // true As mentioned, I don't think TypeBox can reasonably add Will close off this issue for now |
Thank you so much for the quick turnaround on that @sinclairzx81! This is perfect! |
@sachinraja Hey all good. Just a quick note though. I've actually carried out a subsequent update on custom types to accept a schema instance as the first argument of the custom validator function. This to allow some flexibility to specify user defined constraints on the custom type (this if you're currently making use of custom types as the signature for the validation callback has changed) Custom.Set<{ min: bigint, max: bigint }>('BigInt', (schema, value) => {
return typeof value === 'bigint' && value >= schema.min && value <= schema.max)
})
const T = Type.Object({
x: Type.Unsafe<bigint>({ [Kind]: 'BigInt', min: -100n, max: 100n }),
y: Type.Unsafe<bigint>({ [Kind]: 'BigInt', min: -100n, max: 100n }),
z: Type.Unsafe<bigint>({ [Kind]: 'BigInt', min: -100n, max: 100n }),
})
const R = TypeCompiler.Compile(T).Check({ // true
x: 50n,
y: 50n,
z: 50n,
}) Will let this functionality settle for a little while, but I think it should help close the gap for validation requirements that need to work outside the standard JSON schema specification (currently considering using this for mongo Updates are on Cheers |
@sinclairzx81 Has the latest update included |
@NickBeukema Hi,
SerializationPreviously, the Uint8Array, Date types were included as they were directly encode-able in formats such as msgpack. BigInt was included for similar reasons, specifically for the CBOR https://datatracker.ietf.org/doc/html/rfc8949 encoding format. However since the split between Generally, TypeBox tries to provide type representation (at a minimum) for baseline JavaScript primitives (and still pays mind to whether or not a type can be serialized). The library still has reservations for common collection types like Custom / FormatsThese were renamed to the following in 0.26.0
You should be able to just rename from Hope this brings some insights into some of the recent changes in the library, happy to discuss more if you have any follow on questions. |
Hey, I saw that you recently added support for
Date
and was wondering if you could do the same forBigInt
(a JS primitive)? I am willing to implement it myself if you agree that it should be added.If it matters, I'm using the TypeCompiler.
The text was updated successfully, but these errors were encountered: