ForbesLindesay/funtypes

What's the point of deprecation of `check` in favor of `parse`

Closed this issue · 5 comments

yuhr commented

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.

yuhr commented

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.