ForbesLindesay / funtypes

Runtime validation for static types
MIT License
29 stars 4 forks source link

Placeholder-Based Parsing Breaks a Bunch of Stuff #48

Open mrnerdhair opened 3 years ago

mrnerdhair commented 3 years ago

The changes from #17 (specifically, the placeholder-based parsing machinery introduced in 6e58e53) breaks a bunch of stuff.

There are some odd consequences, which violate the static types advertised by Static<A> for each of these kinds of runtypes:

In general, rt.test(x) should imply rt.parse(x) === x -- or at the very least, rt.check(x) === x.

mrnerdhair commented 3 years ago

Here's a gist with some test cases.

ForbesLindesay commented 10 months ago

In general, rt.test(x) should imply rt.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.