z.number().multipleOf(0.01)
can be a clever workaround (even for non-integer values!).
Yet, there's a concern about the IEEE 754 representation problem (it has its own term - though slipped my mind - and isn't exclusive to JS), as shown in this scenario:
z.number().multipleOf(0.01).parse(0.1 + 0.1 + 0.1)
This will throw an error due to the fact that 0.1 + 0.1 + 0.1 actually equals 0.300000000004 internally.
Perhaps using refine()
along with a comparison against Number.EPSILON
could offer a more dependable solution:
z.number()
.refine(x => x * 100 - Math.trunc(x * 100)< Number.EPSILON)
.parse(0.1 + 0.1 + 0.1) // should work fine
[upd] according to @captain-yossarianfromUkraine, Number.EPSILON might address float-number concerns
PS unable to compare this method with the usage of z.custom()
suggested by @vera