-
-
Notifications
You must be signed in to change notification settings - Fork 228
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 issues with enum options filtering logic in enum_ function #941
Fix issues with enum options filtering logic in enum_ function #941
Conversation
* filter out 'NaN' * retain numeric strings that cannot occur in reverse mapping keys such as '1.0'
Thanks for creating this PR! Unfortunately I have almost no time to review and merge it in the next 3 weeks, but I plan to do it before we release our stable v1. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for creating this PR! I look forward to your feedback to merge this PR soon.
I will improve the filtering of reverse mappings, undo the changes to types and merge this PR if you have no objections. |
recognize reverse mapping entries by key and value
commit: |
f41426c
to
d713dfe
Compare
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Thank you! 🧩 |
v1.0.0-beta.10 is available |
The current implementation of the enum_ function in Valibot filters enum options using the following code:
valibot/library/src/schemas/enum/enum.ts
Lines 92 to 98 in 8ab047f
The purpose of this filtering logic is to remove the reverse mapping entries that TypeScript adds when transpiling enums. Specifically, when an enum member is defined as Name = value and value is a number, TypeScript generates a reverse mapping in the form
Enum[value] = 'Name'
. The key of this reverse mapping is stringified by Number.prototype.toString with radix=10 via ToPropertyKey as defined by the ECMAScript specification.There are several issues with using
+key
andisNaN
in the filtering logic:String Conversion: The +key operation follows the StringToNumber abstract operation as defined in the ECMAScript specification. Since
enum_
filters out any number, this operation has several implications:Infinity
or-Infinity
are interpreted as their respective number representations.0b
,0o
, or0x
as binary, octal, or hexadecimal literals.0.1
,.1
, and0
. are all valid and yield the respective numeric values.+
symbol as a valid sign.NaN Values in Enum: If the enum contains
NaN
, as in the following example:The
isNaN
check will not work as expected sinceisNaN(key)
will return true when key is 'NaN', causing the 'NaN' key to be retained rather than filtered out.To correctly filter out these reverse mappings, I made the filtering logic more precise. In this PR, rather than
isNaN
, the parsed value is stringified and is matched against the original key. If it matches, it is filtered out.Additionally, the filtering logic is not reflected in the
EnumSchema
type. For example, when usingenum_({ 1: "A" })
, theoptions
end up being empty, which was not obvious until runtime. Therefore I implemented type-level option filtering.