What's the point of deprecation of `check` in favor of `parse`
Closed this issue · 5 comments
Related to #16, #17, runtypes#56, and maybe #45.
Currently I'm investigating how I can better implement a feature upstream similar to #17, and I want to understand funtypes
' design consideration around this.
It seems that there's direct correspondence between parse
and check
, safeParse
and validate
, each in funtypes
and runtypes
respectively, but I've been told it's like a misunderstand. @MicahZoltu How can I get the actual concepts of these?
They were just renamed. I believe the author of funtypes
didn't like the naming convention of runtypes
, so they just did a rename when they forked.
This rename is separate from the new features that were added such as custom serializers/deserializers.
Oh, I see... Then I want to confirm whether what I assumed about ParsedValue
at this post is wrong or not. Is ParsedValue
just designed to be an all-in-one solution which involves serializeer/deserializer and conformity checker into itself?
ParsedValue
is a serializer/deserializer. You can apply it to a type like:
import * as t from 'funtypes'
// define how to serialize/deserialize a bigint
const BigIntParser: t.ParsedValue<t.String, bigint>['config'] = {
parse: value => {
if (!/^0x([a-fA-F0-9]{0,64})$/.test(value)) return { success: false, message: `${value} is not a hex string encoded number.` }
else return { success: true, value: BigInt(value) }
},
serialize: value => {
return { success: true, value: `0x${value.toString(16)}` }
},
}
// create a custom type definition that uses the bigint serializer
const MyBigInt = t.String.withParser(BigIntParser)
type MyBigint = t.Static<typeof myBigInt>
// run an opaque object/unknown object through the parser
declare const something: unknown
myBigInt = MyBigInt.parse(something) // throws if not a hex encoded string
myBigInt // type: bigint
The parse
vs. check
etc. was just because I wanted to make the naming feel more consistent. There were lots of words that were effectively almost synonyms being used to identify different methods. I decided to pick new terminology and then use it consistently.
@MicahZoltu 's description of the use case for ParsedValue
is correct. It is intended to allow you to define custom parsing and serialising for fields like BigInt or Date that don't have a direct JSON representation.
P.S. the reason for the separate parse
, serialize
and test
config options in ParsedValue
is to match up with the parse
/safeParse
, serialize
/safeSerialize
and assert
/test
methods. When parsing a value it may be possible to convert it into a valid value (e.g. for TrimmedString you could automatically trim the whitespace), but when testing/asserting a value, we cannot modify the original value, so we need a way to check it is already valid.