tcomb
tcomb copied to clipboard
Improve documentation
I'm writing "A little guide to runtime type checking and runtime type introspection" https://github.com/gcanti/tcomb/blob/master/docs/GUIDE.md.
It's an attempt to write down how I use tcomb in my own projects, hope it's helpful to others.
Any comment, suggestion or review is welcome.
Cheers, Giulio
Very helpful, especially the last section on converting Dates, as I've been looking at jsonapi, also id fields are serialized as a string instead of an integer (I wonder if there's an idea for another tcomb library variant in the future? - at the moment I'm using https://github.com/beauby/jsonapi-datastore to parse the responses).
Anyway, in my scenario I found a few issues with the deserialise function:
- I needed to override
fromJSONon arefinement(subtype). listwas missing.- unknown props would throw an error, rather than be ignored as with normal construction.
Here's my version (uses Babel):
t.Date.fromJSON = (s) => s ? new Date(s) : null // allow conversion from ISO-8601
// Deserialize to tcomb type, allows for conversions via a fromJSON function on the type.
export const deserialize = (value, type) => {
// Ignore unknown types, probably extra data that will be ignored anyway.
if (!type) {
return value
}
const { kind } = type.meta
switch (kind) {
case 'struct':
return type(Object.keys(value).reduce((acc, key) => {
acc[key] = deserialize(value[key], type.meta.props[key])
return acc
}, {}))
case 'list':
return type(value.map((element) => deserialize(element, type.meta.type)))
case 'maybe':
return deserialize(value, type.meta.type)
case 'subtype': // the kind of refinement is 'subtype' (for legacy reasons)
// See if custom serializer, else delegate to supertype.
if (t.Function.is(type.fromJSON)) {
return type.fromJSON(value)
}
return deserialize(value, type.meta.type)
case 'enums':
case 'irreducible':
if (t.Function.is(type.fromJSON)) {
return type.fromJSON(value)
}
return value
}
}
Maybe the maybe case should handle null, rather than my t.Date.fromJSON example?
Are there any other types that should be handled? Should the default case throw an error or return value?
Hi @grahamlyus,
The deserialize function is just an example of RTI, it doesn't mean to be complete, but I should mention that, thanks for pointing out!
Are there any other types that should be handled?
Technically tuple, dict, intersection and union are missing.
For a complete implementation, which is very interesting, I opened a issue here https://github.com/gcanti/tcomb/issues/169
it doesn't mean to be complete
However how I'm handling maybe is not good, so I amended the example in GUIDE.md
Is there a quick method to disable runtime checking without needing to run in NODE_ENV=production?
@marwanhilmi not that I'm aware. May I ask you what's your use case?
We use NODE_ENV to toggle our config, ie NODE_ENV=staging so it would be nice to have another option to disable runtime checking without specifically checking for production. Perhaps its own env flag?