Skip to content
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

fix: check if Union type is optional during Encode #782

Closed
wants to merge 1 commit into from

Conversation

aleclarson
Copy link

Since the “optionality” of a Union type is not inherited by its anyOf types, we need to bail out on undefined values when the Union is optional.

Since the “optionality” of a Union type is not inherited by its anyOf types, we need to bail out on `undefined` values when the Union is optional.
@sinclairzx81
Copy link
Owner

@aleclarson Hi,

I like the idea of bailing out of checks and additional processing of values, but may need a bit more context on this. Note that Optional type is only applicable to PropertKeys of Objects where optionality is determined via key in value checks (as opposed to value === undefined) so this logic might make more sense added to the FromObject method (where key enumeration happens). Also note that ability to bail out on Optional may be applicable to all types (so not limited to Union), which also suggests updates to FromObject.

Can you provide a bit more information (mostly code examples)

  1. An example of how the current logic breaks from a end users standpoint (union only)
  2. An example / reproduction of where the logic might be observed from a end users standpoint (union only)

Just need to get my bearings on usage patterns before proceeding on this one.

@sinclairzx81
Copy link
Owner

@aleclarson Hey, just for reference purposes.

import { Value } from '@sinclair/typebox/value'
import { Type } from '@sinclair/typebox'

const NumericDecode = (value: string | boolean) => {
  console.log('decoding...')
  return typeof value === 'boolean' ? value ? 1 : 0 : parseInt(value)
}

const Numeric = Type.Transform(Type.Union([Type.String(), Type.Boolean()]))
  .Decode(NumericDecode)
  .Encode((value) => value.toString())


const T = Type.Object({
  x: Type.Optional(Numeric),
})

// Reference Example

console.log(Value.Decode(T, { }))           // { }        // note: that the 'decoding...' string is not logged as the
                                                          // x property key is not specified on the value.

console.log(Value.Decode(T, { x: true }))   // { x: 1 }   
console.log(Value.Decode(T, { x: false }))  // { x: 0 }   
console.log(Value.Decode(T, { x: '123' }))  // { x: 123 }

The current logic does seem to be omitting decode call when the property is missing (avoiding the need to bail out). But if you have a use case / repro different from the above, just post that below.

Cheers!

@sinclairzx81
Copy link
Owner

@aleclarson Hey might close off this PR as the functionality seems to be working as expected here (and noting some the finer details around undefined and optional properties).

Generally, I think everything is fine here, but if you can draft up a repro and submit as an issue, can maybe take another things.

Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants