Closed sinclairzx81 closed 1 year ago
Special functions like assertStringify()
, assertEncode()
and assertClone()
checks Number.isFinite()
.
As you know, typia
is designed to validate only TypeScript type. In the TypeScript type system, Number.INF
and NaN
are not invalidating number
type. It would be invalidate type only when converting to JSON string or Protocol Buffer data. For an example, the representative use case of assert()
is @nestia.core.TypedBody()
function. It validates request body data after JSON.parse()
function, and it doesn't need to validate Number.isFinite()
after JSON.parse()
.
If you want to turn on the Number.isFinite()
checking manually, configure finite
property as true
in plugin configuration of tsconfig.json
file. Otherwise, use special functions like assertStringify()
(assert()
+ stringify()
) or assertEncode()
(assert()
+ encode()
for Protobol Buffer). As you've said, the Number.isFinite()
(not Number.isNaN()
) must be checked when converting to JSON or Protobuf data and, typia
does it.
@samchon Well, fair enough, however NaN
does literally mean "Not A Number" and I do think the general expectation here would be that Typia would flag it as a default rather than requiring users to opt into it via finite
(which you might want to make a bit more obvious in the docs). But it's good to see it's at least configurable!
Will close off this issue as it sounds default NaN
checks are not likely as a default, and opt in through configuration is quite workable.
Cheers
As above statement is not a compile error in Typescript (of course, it is nonsensible), I have to keep current policy. Also, as I've invented this typia
to support nestia and reactia, I must consider the use that validating after JSON.parse()
.
Unfortunately,
typia
became a little bit famous earlier thannestia
, butnestia
is the ultimate goal of thistypia
. Also, I've completed to implementreactia
, but writing documents and creating example projects are left, and it is hard thing for me to accomplish in leisure time.
Therefore, I decided to not use isNaN()
function as default, but you can turn on the isNaN()
checking on your benchmark program, just by configuring numeric: true, finite: false
config. Thanks for advise.
@samchon It's fine. I think aligning strictly to the policies of TypeScript is quite reasonable with the configuration overrides, so all good there. But please document the numeric
and finite
configs in the readme! (I couldn't find them)
While I do think most people would probably recommend NaN
assertions should be enabled by default (and probably Infinity
too), I can easily see a reason for not implementing them if the goal is to be completely aligned to TypeScript. I've also made similar concessions in TB aligning it to JSON Schema, so I do understand.
Just on the topic of configurations / performance though, you can actually use the following to have TypeBox adopt TypeScript checking semantics as well. This should let you directly measure AOT and JIT performance for equivalent assertion logic. Both of these are false
by default.
import { TypeSystem } from '@sinclair/typebox/system'
TypeSystem.AllowArrayObjects = true
TypeSystem.AllowNaN = true
Would be curious to see the performance cost of NaN
run against varying spoiler
data that you have implemented on the Typia benchmarks. (JIT and AOT performance is somewhat of interest to me atm given the variability I've seen between Node versions). I may take a look at running these later this week (given how these benchmarks currently look)
Anyway, Good work! Typia's looking good (also, glad you went with name change!)
Summary
Hey, have noticed Typia doesn't appear to check for
NaN
values. Note thatNaN
(i.e. Not-A-Number) is a unrepresentable / non-computable IEEE754 numeric that can only result in anotherNaN
. JavaScript supportsNaN
as a consequence of IEEE754; and TypeScript interprets it as anumber
static type, but for validation purposes, not validating for it is a very common source of errors.Comparison
Assertion for
NaN
is generally expected for number validation, the following are a list of libraries I've tested so far.Performance
Note, You are almost certainly going to see a performance degradation as a result of implementing this check (which largely accounts for the excessive performance disparity as shown in your projects readme, specifically
ObjectSimple
). However not implementing this check does put Typia at odds with other validators (and probably at odds with the expectations of users).A possible solution may be to make the
NaN
check configurable (as TypeBox has done to get visibility on this disparity) which will allow Typia to keep on with the 15,000x performance claim, but I do think Typia should probably assert forNaN
by default (with a possible--allow-nan
command line option to allow Typia to opt out ofNaN
checks when benchmarking).Micro Benchmark
The following shows the comparative performance with and without the
NaN
check. When factoring the Point3D check for ObjectSimple, that almost certainly accounts for the 12x performance for this object.System
Node: 16.17.1 Typescript: 4.9.5 Typia: 3.5.4
References
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN https://en.wikipedia.org/wiki/IEEE_754
For consideration