funtypes
funtypes copied to clipboard
Placeholder-Based Parsing Breaks a Bunch of Stuff
The changes from #17 (specifically, the placeholder-based parsing machinery introduced in 6e58e53) breaks a bunch of stuff.
- Placeholders don't preserve the prototype chain, so
instanceofbreaks - Placeholders are filled by iteration over an object's own string properties, so you lose anything that's not in there
- Like own symbol properties
- Or anything private/closure-scoped, like Map state
- Placeholders are always used when parsing Intersect types
- Placeholders are always used when parsing Object types
- Placeholder-filled properties become writable, enumerable, and configurable
- Placeholder-filled properties don't preserve getters and setters
There are some odd consequences, which violate the static types advertised by Static<A> for each of these kinds of runtypes:
Never.Or(InstanceOf(Foo)).parse(x)is aninstanceof Foo, butUnknown.And(InstanceOf(Foo)).parse(x)is not- Stuff like
InstanceOf(Uint8Array).And(Object({length: Literal(32)}))produces array-like objects that aren't arrays or Uint8Arrays
In general, rt.test(x) should imply rt.parse(x) === x -- or at the very least, rt.check(x) === x.
Here's a gist with some test cases.
In general,
rt.test(x)should implyrt.parse(x) === x
This may be nice, but it's not true at all. rt.parse(x) drops unexpected properties by default. This is intentional behaviour, and is useful & correct.
TypeScript doesn't really generally respect instanceof normally anyway. For example, TypeScript thinks this is valid:
class Point {
public x: number;
public y: number;
}
function logPoint(p: Point) {
console.log(`(${p.x}, ${p.y}`);
}
logPoint({x: 1, y: 2});
funtypes does duck-typing much like TypeScript. It's primarily intended for validating API types, where the objects will generally be primitive types, not instances of classes. The InstanceOf codec is primarily there as an escape hatch and to support the test in ParsedValues. If you need to preserve prototype chains you can use test / assert. If you need parsing rather than just validation, you can use parse / safeParse. I think it's ok that this limitation exists.